Skip to content

Commit

Permalink
Migrate to Pydantic 2.0 standards (#195)
Browse files Browse the repository at this point in the history
  • Loading branch information
bachya committed Aug 15, 2023
1 parent 4a58893 commit 8858f48
Show file tree
Hide file tree
Showing 12 changed files with 208 additions and 384 deletions.
10 changes: 5 additions & 5 deletions aiopurpleair/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

from aiohttp import ClientSession, ClientTimeout
from aiohttp.client_exceptions import ClientError
from pydantic.v1 import BaseModel, ValidationError
from pydantic import ValidationError

from aiopurpleair.const import LOGGER
from aiopurpleair.endpoints.sensors import SensorsEndpoints
from aiopurpleair.errors import RequestError, raise_error
from aiopurpleair.helpers.typing import ModelT
from aiopurpleair.helpers.model import PurpleAirBaseModel, PurpleAirBaseModelT
from aiopurpleair.models.keys import GetKeysResponse

API_URL_BASE = "https://api.purpleair.com/v1"
Expand Down Expand Up @@ -52,9 +52,9 @@ async def async_request(
self,
method: str,
endpoint: str,
response_model: type[BaseModel],
response_model: type[PurpleAirBaseModel],
**kwargs: dict[str, Any],
) -> ModelT:
) -> PurpleAirBaseModelT:
"""Make an API request.
Args:
Expand Down Expand Up @@ -100,7 +100,7 @@ async def async_request(
LOGGER.debug("Data received for %s: %s", endpoint, data)

try:
return cast(ModelT, response_model.parse_obj(data))
return cast(PurpleAirBaseModelT, response_model.model_validate(data))
except ValidationError as err:
raise RequestError(
f"Error while parsing response from {endpoint}: {err}"
Expand Down
21 changes: 13 additions & 8 deletions aiopurpleair/endpoints/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
from collections.abc import Awaitable, Callable, Iterable
from typing import Any

from pydantic.v1 import BaseModel, ValidationError
from pydantic import ValidationError

from aiopurpleair.errors import InvalidRequestError
from aiopurpleair.helpers.typing import ModelT
from aiopurpleair.helpers.model import PurpleAirBaseModel, PurpleAirBaseModelT


class APIEndpointsBase: # pylint: disable=too-few-public-methods
"""Define a base API endpoints manager."""

def __init__(self, async_request: Callable[..., Awaitable[ModelT]]) -> None:
def __init__(
self, async_request: Callable[..., Awaitable[PurpleAirBaseModelT]]
) -> None:
"""Initialize.
Args:
Expand All @@ -25,9 +27,9 @@ async def _async_endpoint_request_with_models(
self,
endpoint: str,
query_param_map: Iterable[tuple[str, Any]],
request_model: type[BaseModel],
response_model: type[BaseModel],
) -> ModelT:
request_model: type[PurpleAirBaseModel],
response_model: type[PurpleAirBaseModel],
) -> PurpleAirBaseModelT:
"""Perform an API endpoint request.
Args:
Expand All @@ -43,7 +45,7 @@ async def _async_endpoint_request_with_models(
InvalidRequestError: Raised on invalid parameters.
"""
try:
request = request_model.parse_obj(
request = request_model.model_validate(
{
api_query_param: func_param
for api_query_param, func_param in query_param_map
Expand All @@ -54,5 +56,8 @@ async def _async_endpoint_request_with_models(
raise InvalidRequestError(err) from err

return await self._async_request(
"get", endpoint, response_model, params=request.dict(exclude_none=True)
"get",
endpoint,
response_model,
params=request.model_dump(exclude_none=True),
)
13 changes: 13 additions & 0 deletions aiopurpleair/helpers/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Define model helpers."""
from typing import TypeVar

from pydantic import BaseModel, ConfigDict


class PurpleAirBaseModel(BaseModel):
"""Define a PurpleAir-specific base model."""

model_config = ConfigDict(frozen=True)


PurpleAirBaseModelT = TypeVar("PurpleAirBaseModelT", bound=PurpleAirBaseModel)
6 changes: 0 additions & 6 deletions aiopurpleair/helpers/typing.py

This file was deleted.

File renamed without changes.
File renamed without changes.
21 changes: 7 additions & 14 deletions aiopurpleair/models/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

from datetime import datetime

from pydantic.v1 import BaseModel, validator
from pydantic import Field, field_validator

from aiopurpleair.backports.enum import StrEnum
from aiopurpleair.helpers.validators import validate_timestamp
from aiopurpleair.helpers.model import PurpleAirBaseModel
from aiopurpleair.helpers.validator import validate_timestamp


class ApiKeyType(StrEnum):
Expand All @@ -19,22 +20,14 @@ class ApiKeyType(StrEnum):
WRITE_DISABLED = "WRITE_DISABLED"


class GetKeysResponse(BaseModel):
class GetKeysResponse(PurpleAirBaseModel):
"""Define a response to GET /v1/keys."""

api_key_type: str
api_version: str
timestamp_utc: datetime
timestamp_utc: datetime = Field(alias="time_stamp")

class Config: # pylint: disable=too-few-public-methods
"""Define configuration for this model."""

fields = {
"timestamp_utc": {"alias": "time_stamp"},
}
frozen = True

@validator("api_key_type")
@field_validator("api_key_type")
@classmethod
def validate_api_key_type(cls, value: str) -> ApiKeyType:
"""Validate the API key type.
Expand All @@ -53,6 +46,6 @@ def validate_api_key_type(cls, value: str) -> ApiKeyType:
except ValueError as err:
raise ValueError(f"{value} is an unknown API key type") from err

validate_utc_timestamp = validator("timestamp_utc", allow_reuse=True, pre=True)(
validate_utc_timestamp = field_validator("timestamp_utc", mode="before")(
validate_timestamp
)
Loading

0 comments on commit 8858f48

Please sign in to comment.