Skip to content

Commit

Permalink
Migrate dataclasses-json to mashumaro (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpbede authored Jan 24, 2024
1 parent 94505e5 commit c189110
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 150 deletions.
11 changes: 10 additions & 1 deletion aioelectricitymaps/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
"""ElectricityMaps wrapper."""
from .electricitymaps import ElectricityMaps
from .exceptions import ElectricityMapsDecodeError, ElectricityMapsError, InvalidToken
from .models import CarbonIntensityResponse, Zone

__all__ = ["ElectricityMaps"]
__all__ = [
"ElectricityMaps",
"ElectricityMapsDecodeError",
"ElectricityMapsError",
"InvalidToken",
"CarbonIntensityResponse",
"Zone",
]
16 changes: 7 additions & 9 deletions aioelectricitymaps/electricitymaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
InvalidToken,
SwitchedToLegacyAPI,
)
from .marshmallow import ZoneList
from .models import CarbonIntensityResponse, Zone
from .models import CarbonIntensityResponse, Zone, ZonesResponse

_LOGGER = logging.getLogger(__name__)

Expand All @@ -32,14 +31,13 @@ class ElectricityMaps:
_close_session: bool = False
_is_legacy_token: bool = False

async def _get(self, url: str, params: dict[str, Any] | None = None) -> Any:
async def _get(self, url: str, params: dict[str, Any] | None = None) -> str:
"""Execute a GET request against the API."""
if self.session is None:
self.session = ClientSession()
self._close_session = True

headers = {"auth-token": self.token}
parsed = {}

_LOGGER.debug("Doing request: GET %s %s", url, str(params))

Expand Down Expand Up @@ -86,7 +84,7 @@ async def _get(self, url: str, params: dict[str, Any] | None = None) -> Any:

raise InvalidToken

return parsed
return await response.text()

@retry_legacy
async def latest_carbon_intensity_by_coordinates(
Expand All @@ -105,7 +103,7 @@ async def latest_carbon_intensity_by_coordinates(
ApiEndpoints.CARBON_INTENSITY,
{"lat": lat, "lon": lon},
)
return CarbonIntensityResponse.from_dict(result)
return CarbonIntensityResponse.from_json(result)

@retry_legacy
async def latest_carbon_intensity_by_country_code(
Expand All @@ -120,12 +118,12 @@ async def latest_carbon_intensity_by_country_code(
)
else:
result = await self._get(ApiEndpoints.CARBON_INTENSITY, {"zone": code})
return CarbonIntensityResponse.from_dict(result)
return CarbonIntensityResponse.from_json(result)

async def zones(self) -> dict[str, Zone]:
"""Get list of zones where carbon intensity is available."""
"""Get a dict of zones where carbon intensity is available."""
result = await self._get(ApiEndpoints.ZONES)
return ZoneList.from_dict({"zones": result}).zones
return ZonesResponse.from_json(result).zones

async def close(self) -> None:
"""Close open client session."""
Expand Down
23 changes: 0 additions & 23 deletions aioelectricitymaps/marshmallow.py

This file was deleted.

61 changes: 40 additions & 21 deletions aioelectricitymaps/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,60 @@
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Self

from dataclasses_json import DataClassJsonMixin, LetterCase, config
from mashumaro import field_options
from mashumaro.mixins.orjson import DataClassORJSONMixin


@dataclass(slots=True, frozen=True)
class CarbonIntensityData(DataClassJsonMixin):
"""Data field."""
@dataclass(slots=True, frozen=True, kw_only=True)
class CarbonIntensityResponse(DataClassORJSONMixin):
"""API response."""

carbon_intensity: float = field(metadata=config(letter_case=LetterCase.CAMEL))
fossil_fuel_percentage: float = field(metadata=config(letter_case=LetterCase.CAMEL))
status: str
country_code: str = field(metadata=field_options(alias="countryCode"))
data: CarbonIntensityData
units: CarbonIntensityUnit


@dataclass(slots=True, frozen=True)
class CarbonIntensityUnit(DataClassJsonMixin):
"""Unit field."""
@dataclass(slots=True, frozen=True, kw_only=True)
class ZonesResponse(DataClassORJSONMixin):
"""Zones API response."""

carbon_intensity: str = field(metadata=config(letter_case=LetterCase.CAMEL))
zones: dict[str, Zone]

@classmethod
def __pre_deserialize__(
cls: type[Self],
d: dict[Any, Any],
) -> dict[Any, Any]:
"""Wrap data in a dict for deserialization."""
return {"zones": d}

@dataclass(slots=True, frozen=True)
class CarbonIntensityResponse(DataClassJsonMixin):
"""API response."""

status: str = field(metadata=config(letter_case=LetterCase.CAMEL))
country_code: str = field(metadata=config(letter_case=LetterCase.CAMEL))
data: CarbonIntensityData
units: CarbonIntensityUnit
@dataclass(slots=True, frozen=True, kw_only=True)
class CarbonIntensityData:
"""Data field."""

carbon_intensity: float = field(metadata=field_options(alias="carbonIntensity"))
fossil_fuel_percentage: float = field(
metadata=field_options(alias="fossilFuelPercentage"),
)


@dataclass(slots=True, frozen=True, kw_only=True)
class CarbonIntensityUnit:
"""Unit field."""

carbon_intensity: str = field(metadata=field_options(alias="carbonIntensity"))


@dataclass(slots=True, frozen=True)
class Zone(DataClassJsonMixin):
@dataclass(slots=True, frozen=True, kw_only=True)
class Zone:
"""Zone for carbon intensity API."""

zone_name: str = field(metadata=config(letter_case=LetterCase.CAMEL))
zone_name: str = field(metadata=field_options(alias="zoneName"))
country_name: str | None = field(
metadata=config(letter_case=LetterCase.CAMEL),
metadata=field_options(alias="countryName"),
default=None,
)
Loading

0 comments on commit c189110

Please sign in to comment.