Skip to content

Commit

Permalink
Merge pull request #5 from pingpingy1/main
Browse files Browse the repository at this point in the history
[feat] 연령 히스토그램 endpoint 추가
  • Loading branch information
happycastle114 authored Nov 22, 2023
2 parents d14b531 + 1b58d76 commit ace8306
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 3 deletions.
3 changes: 2 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from fastapi import FastAPI, Request
from dotenv import load_dotenv
from routers import scrapResult, commonInfo
from routers import scrapResult, commonInfo, ageHist
from contextlib import asynccontextmanager
from typing import Dict
from model import MongoDB
Expand All @@ -21,3 +21,4 @@ async def initMongo(app: FastAPI):

app.include_router(scrapResult.router)
app.include_router(commonInfo.router)
app.include_router(ageHist.router)
30 changes: 30 additions & 0 deletions model/AgeHist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from pydantic import BaseModel
from enum import StrEnum


class AgeHistDataTypes(StrEnum):
elected = "elected"
candidate = "candidate"


class AgeHistMethodTypes(StrEnum):
equal = "equal"
kmeans = "kmeans"


class AgeHistDataPoint(BaseModel):
minAge: int
maxAge: int
count: int
ageGroup: int


class MetroAgeHistData(BaseModel):
metroId: int
data: list[AgeHistDataPoint]


class LocalAgeHistData(BaseModel):
metroId: int
localId: int
data: list[AgeHistDataPoint]
1 change: 1 addition & 0 deletions model/BasicResponse.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

SUCCESS = 200
REGION_CODE_ERR = 400
COLLECTION_NOT_EXIST_ERR = 600


class MessageResponse(BaseModel):
Expand Down
2 changes: 2 additions & 0 deletions model/MongoDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ def __init__(self):
self.client = None
self.council_db = None
self.district_db = None
self.age_hist_db = None

def connect(self):
self.client = AsyncIOMotorClient(os.getenv("MONGO_CONNECTION_URI"))
self.council_db = AsyncIOMotorDatabase(self.client, "council")
self.district_db = AsyncIOMotorDatabase(self.client, "district")
self.age_hist_db = AsyncIOMotorDatabase(self.client, "age_hist")

def close(self):
self.client.close()
Expand Down
2 changes: 1 addition & 1 deletion model/ScrapResult.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class GenderChartDataPoint(BaseModel):

class AgeChartDataPoint(BaseModel):
minAge: int # 닫힌 구간
maxAge: int # 닫힌 구간
maxAge: int # 열린 구간
count: int


Expand Down
94 changes: 94 additions & 0 deletions routers/ageHist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from fastapi import APIRouter
from model import BasicResponse, MongoDB
from model.AgeHist import AgeHistDataTypes, AgeHistMethodTypes, MetroAgeHistData


router = APIRouter(prefix="/localCouncil", tags=["localCouncil"])


@router.get("/age-hist/{metroId}")
async def getMetroAgeHistData(
metroId: int, ageHistType: AgeHistDataTypes, year: int, method: AgeHistMethodTypes
) -> BasicResponse.ErrorResponse | MetroAgeHistData:
if (
await MongoDB.client.district_db["metro_district"].find_one(
{"metroId": metroId}
)
is None
):
return BasicResponse.ErrorResponse.model_validate(
{
"error": "RegionCodeError",
"code": BasicResponse.REGION_CODE_ERR,
"message": f"No metro district with metroId {metroId}.",
}
)

match ageHistType:
case AgeHistDataTypes.elected:
collection_name = f"지선-당선_{year}_1level_{method}"
case AgeHistDataTypes.candidate:
collection_name = f"지선-후보_{year}_1level_{method}"

if collection_name not in await MongoDB.client.age_hist_db.list_collection_names():
return BasicResponse.ErrorResponse.model_validate(
{
"error": "CollectionNotExistError",
"code": BasicResponse.COLLECTION_NOT_EXIST_ERR,
"message": f"No collection with name f{collection_name}. Perhaps the year is wrong?",
}
)

histogram = await MongoDB.client.age_hist_db[collection_name].find_one(
{"metroId": metroId}
)

return MetroAgeHistData.model_validate(
{"metroId": metroId, "data": histogram["data"]}
)


@router.get("/age-hist/{metroId}/{localId}")
async def getLocalAgeHistData(
metroId: int,
localId: int,
ageHistType: AgeHistDataTypes,
year: int,
method: AgeHistMethodTypes,
) -> BasicResponse.ErrorResponse | MetroAgeHistData:
if (
await MongoDB.client.district_db["local_district"].find_one(
{"metroId": metroId, "localId": localId}
)
is None
):
return BasicResponse.ErrorResponse.model_validate(
{
"error": "RegionCodeError",
"code": BasicResponse.REGION_CODE_ERR,
"message": f"No local district with metroId {metroId} and localId {localId}.",
}
)

match ageHistType:
case AgeHistDataTypes.elected:
collection_name = f"지선-당선_{year}_2level_{method}"
case AgeHistDataTypes.candidate:
collection_name = f"지선-후보_{year}_2level_{method}"

if collection_name not in await MongoDB.client.age_hist_db.list_collection_names():
return BasicResponse.ErrorResponse.model_validate(
{
"error": "CollectionNotExistError",
"code": BasicResponse.COLLECTION_NOT_EXIST_ERR,
"message": f"No collection with name f{collection_name}. Perhaps the year is wrong?",
}
)

histogram = await MongoDB.client.age_hist_db[collection_name].find_one(
{"metroId": metroId, "localId": localId}
)

return MetroAgeHistData.model_validate(
{"metroId": metroId, "localId": localId, "data": histogram["data"]}
)
2 changes: 1 addition & 1 deletion routers/scrapResult.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ async def getLocalChartData(
"data": [
{
"minAge": age,
"maxAge": age + AGE_STAIR - 1,
"maxAge": age + AGE_STAIR,
"count": age_count[age],
}
for age in age_count
Expand Down

0 comments on commit ace8306

Please sign in to comment.