Skip to content
This repository has been archived by the owner on Jan 18, 2025. It is now read-only.

Commit

Permalink
refactor(config): define API also as list, constraint list length
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinNitroG committed Jan 10, 2025
1 parent dd1aa79 commit dbb2c20
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 105 deletions.
124 changes: 54 additions & 70 deletions schemas/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,24 @@
"$defs": {
"ApiEnum": {
"enum": [
"all",
"checkphatnguoi.vn",
"csgt.vn"
],
"title": "ApiEnum",
"type": "string"
},
"BaseNotificationConfig": {
"properties": {
"enabled": {
"default": true,
"description": "Kích hoạt",
"title": "Enabled",
"type": "boolean"
}
},
"title": "Lớp cơ sở notification bao gồm trường enabled cho các lớp kế thừa",
"type": "object"
},
"PlateInfo": {
"properties": {
"plate": {
Expand Down Expand Up @@ -39,35 +50,46 @@
"description": "Loại phương tiện để gửi request cũng như lọc loại phương tiện đối với các API không lọc loại phương tiện sẵn",
"title": "Loại phương tiện"
},
"owner": {
"api": {
"anyOf": [
{
"type": "string"
"anyOf": [
{
"items": {
"$ref": "#/$defs/ApiEnum"
},
"type": "array"
},
{
"$ref": "#/$defs/ApiEnum"
}
],
"minLength": 1
},
{
"type": "null"
}
],
"default": null,
"description": "Ghi chú chủ sở hữu (phù hợp khi dùng nhắc ai đó với lựa chọn notifications)",
"examples": [
"@kevinnitro",
"dad"
],
"title": "Ghi chú chủ sở hữu"
"description": "Sử dụng API từ trang web nào. Config giống \"api\" ở ngoài .Để trống sẽ sử dụng API define ở scope ngoài.",
"title": "API"
},
"api": {
"owner": {
"anyOf": [
{
"$ref": "#/$defs/ApiEnum"
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Sử dụng API từ trang web nào (để trống sẽ sử dụng API define ở scope ngoài)",
"title": "API"
"description": "Ghi chú chủ sở hữu (phù hợp khi dùng nhắc ai đó với lựa chọn notifications)",
"examples": [
"@kevinnitro",
"dad"
],
"title": "Ghi chú chủ sở hữu"
}
},
"required": [
Expand All @@ -77,51 +99,6 @@
"title": "Thông tin thiết lập cho biển số",
"type": "object"
},
"TelegramNotificationConfig": {
"properties": {
"enabled": {
"default": true,
"description": "Kích hoạt",
"title": "Enabled",
"type": "boolean"
},
"telegram": {
"$ref": "#/$defs/TelegramNotificationEngineConfig",
"description": "Telegram"
}
},
"required": [
"telegram"
],
"title": "Telegram và kích hoạt",
"type": "object"
},
"TelegramNotificationEngineConfig": {
"properties": {
"bot_token": {
"description": "Bot token Telegram",
"examples": [
"2780473231:weiruAShGUUx4oLOMoUhd0GiREXSZcCq-uB"
],
"title": "Bot Token",
"type": "string"
},
"chat_id": {
"description": "Chat ID Telegram",
"examples": [
"-1001790012349"
],
"title": "Chat Id",
"type": "string"
}
},
"required": [
"bot_token",
"chat_id"
],
"title": "Telegram",
"type": "object"
},
"VehicleTypeEnum": {
"enum": [
1,
Expand All @@ -133,34 +110,41 @@
}
},
"properties": {
"plates": {
"plates_infos": {
"description": "Danh sách các biển xe",
"items": {
"$ref": "#/$defs/PlateInfo"
},
"minItems": 1,
"title": "Danh sách biển xe",
"type": "array"
},
"notifications": {
"description": "Danh sách các thiết lập để thông báo",
"items": {
"$ref": "#/$defs/BaseNotificationConfig"
},
"title": "Danh sách thông báo",
"type": "array"
},
"api": {
"anyOf": [
{
"items": {
"$ref": "#/$defs/TelegramNotificationConfig"
"$ref": "#/$defs/ApiEnum"
},
"type": "array"
},
{
"type": "null"
"$ref": "#/$defs/ApiEnum"
}
],
"default": null,
"description": "Danh sách các thiết lập để thông báo",
"title": "Danh sách thông báo"
},
"api": {
"$ref": "#/$defs/ApiEnum",
"default": "checkphatnguoi.vn",
"description": "Sử dụng API từ trang web nào (mặc định sử dụng API từ trang checkphatnguoi.vn)",
"default": [
"checkphatnguoi.vn",
"csgt.vn"
],
"description": "Sử dụng API từ trang web nào. Mặc định sẽ là list các API và dừng khi 1 API lấy dữ liệu thành công. Có thể điền giá trị trùng để retry. Hoặc chỉ dùng 1 API.",
"minLength": 1,
"title": "API"
},
"pending_fines_only": {
Expand Down Expand Up @@ -210,7 +194,7 @@
}
},
"required": [
"plates"
"plates_infos"
],
"title": "Config",
"type": "object"
Expand Down
18 changes: 11 additions & 7 deletions src/check_phat_nguoi/config/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

from check_phat_nguoi.types import ApiEnum, LogLevelType

from .notifications import TelegramNotificationConfig
from .notifications.base_notification import (
BaseNotificationConfig,
)
from .plate_info import PlateInfo


Expand All @@ -15,19 +17,21 @@ class Config(BaseModel):
frozen=True,
)

plates: tuple[PlateInfo, ...] = Field(
plates_infos: tuple[PlateInfo, ...] = Field(
title="Danh sách biển xe",
description="Danh sách các biển xe",
min_length=1,
)
notifications: tuple[TelegramNotificationConfig, ...] | None = Field(
notifications: tuple[BaseNotificationConfig, ...] = Field(
title="Danh sách thông báo",
description="Danh sách các thiết lập để thông báo",
default=None,
default_factory=tuple,
)
api: ApiEnum = Field(
api: tuple[ApiEnum, ...] | ApiEnum = Field(
title="API",
description="Sử dụng API từ trang web nào (mặc định sử dụng API từ trang checkphatnguoi.vn)",
default=ApiEnum.checkphatnguoi_vn,
description="Sử dụng API từ trang web nào. Mặc định sẽ là list các API và dừng khi 1 API lấy dữ liệu thành công. Có thể điền giá trị trùng để retry. Hoặc chỉ dùng 1 API.",
default=(ApiEnum.checkphatnguoi_vn, ApiEnum.csgt_vn),
min_length=1,
)
pending_fines_only: bool = Field(
title="Lọc chưa nộp phạt",
Expand Down
11 changes: 6 additions & 5 deletions src/check_phat_nguoi/config/models/plate_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ class PlateInfo(BaseModel):
description="Loại phương tiện để gửi request cũng như lọc loại phương tiện đối với các API không lọc loại phương tiện sẵn",
title="Loại phương tiện",
)
api: tuple[ApiEnum, ...] | ApiEnum | None = Field(
description='Sử dụng API từ trang web nào. Config giống "api" ở ngoài .Để trống sẽ sử dụng API define ở scope ngoài.',
title="API",
default=None,
min_length=1,
)
owner: str | None = Field(
description="Ghi chú chủ sở hữu (phù hợp khi dùng nhắc ai đó với lựa chọn notifications)",
title="Ghi chú chủ sở hữu",
examples=["@kevinnitro", "dad"],
default=None,
)
api: ApiEnum | None = Field(
description="Sử dụng API từ trang web nào (để trống sẽ sử dụng API define ở scope ngoài)",
title="API",
default=None,
)

@override
def __hash__(self):
Expand Down
1 change: 1 addition & 0 deletions src/check_phat_nguoi/get_data/engines/check_phat_nguoi.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ async def _get_data_request(self, plate_info: PlateInfo) -> Dict | None:
response_data = await response.read()
logger.info(f"Plate {plate_info.plate}: Get data successfully")
return json.loads(response_data)
# TODO: Show API enum instead of URL
except TimeoutError as e:
logger.error(
f"Plate {plate_info.plate}: Time out ({self.timeout}s) getting data from API {API_URL}\n{e}"
Expand Down
51 changes: 29 additions & 22 deletions src/check_phat_nguoi/get_data/get_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,45 @@
class GetData:
def __init__(self) -> None:
self._engine_cpn: GetDataEngineCheckPhatNguoi
self._plates_infos: set[PlateDetail] = set()
self._plates_details: set[PlateDetail] = set()

async def _get_data_for_plate(self, plate_info: PlateInfo) -> None:
plate_detail: PlateDetail | None
if plate_info.api == ApiEnum.all or (
plate_info.api is None and config.api == ApiEnum.all
):
plate_detail = await self._engine_cpn.get_data(plate_info)
# TODO: This is for later other API engine is done
# if plate_info is None:
# plate_info = await self.csgt.get_data(plate)
else:
get_data_engine: BaseGetDataEngine
match api := (plate_info.api or config.api):
# NOTE: The config has constraint that config.api will be at least 1 api in tuple
apis: tuple[ApiEnum, ...] = (
plate_info.api
if isinstance(plate_info.api, tuple)
else (plate_info.api,)
if plate_info.api is not None
else config.api
if isinstance(config.api, tuple)
else (config.api,)
)
get_data_engine: BaseGetDataEngine
for api in apis:
match api:
case ApiEnum.checkphatnguoi_vn:
get_data_engine = self._engine_cpn
case ApiEnum.csgt_vn:
# TODO: @Nguyen thay get_data_engine
logger.error("csgt.vn has't been implemented yet")
return
case _: # Never reach
logger.error(f"Plate {plate_info.plate} - {api}: Not defined!")
return
logger.info(f"Plate {plate_info.plate}: Getting data...")
plate_detail = await get_data_engine.get_data(plate_info)
if plate_detail is None:
return
self._plates_infos.add(plate_detail)
logger.info(
f"Plate {plate_info.plate}: Getting data with API: {api.value}..."
)

plate_detail: PlateDetail | None = await get_data_engine.get_data(
plate_info
)
if plate_detail is not None:
self._plates_details.add(plate_detail)
return

async def get_data(self) -> None:
async with GetDataEngineCheckPhatNguoi() as self._engine_cpn:
await gather(
*(self._get_data_for_plate(plate_info) for plate_info in config.plates)
*(
self._get_data_for_plate(plate_info)
for plate_info in config.plates_infos
)
)
plates_context.set_plates(plates=tuple(self._plates_infos))
plates_context.set_plates(plates=tuple(self._plates_details))
1 change: 0 additions & 1 deletion src/check_phat_nguoi/types/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


class ApiEnum(str, Enum):
all = "all"
checkphatnguoi_vn = "checkphatnguoi.vn"
csgt_vn = "csgt.vn"

Expand Down

0 comments on commit dbb2c20

Please sign in to comment.