Skip to content

Commit d7040b7

Browse files
committed
Add support for inflation
1 parent 843a085 commit d7040b7

File tree

7 files changed

+404
-4
lines changed

7 files changed

+404
-4
lines changed

apininjas/client.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@
3535
CurrencyConversion,
3636
Currency,
3737
IBANValidation,
38+
Inflation,
3839
)
39-
from .enums import CommodityType
40+
from .enums import CommodityType, InflationCountry, InflationIndicatorType
4041
from .errors import StockNotFound
42+
from .utils import MISSING
4143

4244
if TYPE_CHECKING:
4345
from typing_extensions import Self
@@ -299,3 +301,61 @@ async def fetch_iban_validation(self, iban: str) -> IBANValidation:
299301
"""
300302
data = await self._http.get_iban_validation(iban=iban)
301303
return IBANValidation(data=data)
304+
305+
async def fetch_inflation(
306+
self, country: InflationCountry, *, type: InflationIndicatorType = MISSING
307+
) -> Inflation:
308+
"""|coro|
309+
310+
Retrieves an :class:`Inflation` with the specified country.
311+
312+
Parameters
313+
----------
314+
country: :class:`str`
315+
The country to retrieve from.
316+
type: :class:`InflationIndicatorType`
317+
The inflation indicator type.
318+
319+
Raises
320+
-------
321+
HTTPException
322+
Retrieving the inflation failed.
323+
324+
Returns
325+
-------
326+
:class:`Inflation`
327+
The retrieved inflation.
328+
"""
329+
fields = {"country": country.value}
330+
if type is not MISSING:
331+
fields["type"] = type.value
332+
333+
data = await self._http.get_inflation(**fields)
334+
return Inflation(data=data[0])
335+
336+
async def fetch_inflations(self, *, type: InflationIndicatorType = MISSING) -> List[Inflation]:
337+
"""|coro|
338+
339+
Retrieves a list of available :class:`Inflation`.
340+
341+
Parameters
342+
----------
343+
type: :class:`InflationIndicatorType`
344+
The inflation indicator type.
345+
346+
Raises
347+
-------
348+
HTTPException
349+
Retrieving the inflation failed.
350+
351+
Returns
352+
-------
353+
List[:class:`Inflation`]
354+
The retrieved list of available inflation.
355+
"""
356+
fields = {}
357+
if type is not MISSING:
358+
fields["type"] = type.value
359+
360+
data = await self._http.get_inflation(**fields)
361+
return [Inflation(data=inflation) for inflation in data]

apininjas/enums.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
# fmt: off
2929
__all__ = (
3030
"CommodityType",
31+
"InflationIndicatorType",
32+
"InflationCountry",
3133
)
3234
# fmt: on
3335

@@ -84,3 +86,51 @@ class CommodityType(enum.Enum, metaclass=EnumMeta):
8486
gasoline_rbob = "gasoline_rbob"
8587
heating_oil = "heating_oil"
8688
class_3_milk = "class_3_milk"
89+
90+
91+
class InflationIndicatorType(enum.Enum, metaclass=EnumMeta):
92+
cpi = "CPI"
93+
hicp = "HICP"
94+
95+
96+
class InflationCountry(enum.Enum, metaclass=EnumMeta):
97+
austria = "Austria"
98+
belgium = "Belgium"
99+
brazil = "Brazil"
100+
canada = "Canada"
101+
chile = "Chile"
102+
china = "China"
103+
czech_republic = "Czech Republic"
104+
czechia = czech_republic
105+
denmark = "Denmark"
106+
estonia = "Estonia"
107+
finland = "Finland"
108+
france = "France"
109+
germany = "Germany"
110+
greece = "Greece"
111+
hungary = "Hungary"
112+
iceland = "Iceland"
113+
india = "India"
114+
indonesia = "Indonesia"
115+
ireland = "Ireland"
116+
israel = "Israel"
117+
italy = "Italy"
118+
japan = "Japan"
119+
mexico = "Mexico"
120+
norway = "Norway"
121+
poland = "Poland"
122+
portugal = "Portugal"
123+
russia = "Russia"
124+
slovakia = "Slovakia"
125+
slovenia = "Slovenia"
126+
south_korea = "South Korea"
127+
south_africa = "South Africa"
128+
spain = "Spain"
129+
sweden = "Sweden"
130+
switzerland = "Switzerland"
131+
netherlands = "The Netherlands"
132+
turkiye = "Türkiye"
133+
united_kingdom = "United Kingdom"
134+
uk = united_kingdom
135+
united_states = "United States"
136+
usa = united_states

apininjas/finance.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@
2424

2525
from __future__ import annotations
2626

27+
import datetime
2728
from typing import TYPE_CHECKING, Optional, Union, NamedTuple
2829

2930
import apininjas.abc
30-
from .enums import CommodityType
31+
from .enums import CommodityType, InflationIndicatorType, InflationCountry
3132
from . import utils
3233

3334
if TYPE_CHECKING:
@@ -38,6 +39,7 @@
3839
Gold as GoldPayload,
3940
Crypto as CryptoPayload,
4041
IBANValidation as IBANValidationPayload,
42+
Inflation as InflationPayload,
4143
)
4244

4345

@@ -48,6 +50,7 @@
4850
"Commodity",
4951
"Currency",
5052
"IBANValidation",
53+
"Inflation",
5154
)
5255
# fmt: on
5356

@@ -488,3 +491,65 @@ def is_valid(self) -> bool:
488491
This only includes the IBAN checksum validation.
489492
"""
490493
return self.valid
494+
495+
496+
class Inflation:
497+
"""Represents the inflation of a country from the Inflation API.
498+
499+
.. container:: operations
500+
501+
.. describe:: x == y
502+
503+
Checks if two inflations are equal.
504+
505+
.. describe:: x != y
506+
507+
Checks if two inflations are not equal.
508+
509+
Attributes
510+
-----------
511+
country: :class:`str`
512+
The country to which the inflation belongs.
513+
type: :class:`InflationIndicatorType`
514+
The type of inflation indicator.
515+
monthly_rate: :class:`float`
516+
The inflation rate on a monthly basis, in percent.
517+
yearly_rate: :class:`float`
518+
The inflation rate on a yearly basis, in percent.
519+
"""
520+
521+
__slots__ = ("country", "type", "monthly_rate", "yearly_rate", "_period")
522+
523+
def __init__(self, *, data: InflationPayload):
524+
self.country: InflationCountry = InflationCountry(data["country"])
525+
self.type: InflationIndicatorType = InflationIndicatorType(data["type"])
526+
self.monthly_rate: float = data["monthly_rate_pct"]
527+
self.yearly_rate: float = data["yearly_rate_pct"]
528+
self._period: str = data["period"]
529+
530+
def __repr__(self) -> str:
531+
attrs = [
532+
("country", self.country),
533+
("type", self.type),
534+
]
535+
joined = " ".join([f"{a}={v!r}" for a, v in attrs])
536+
return f"<Inflation {joined}>"
537+
538+
def __eq__(self, other: Inflation) -> bool:
539+
return self.country == other.country and self.type == other.type and self.period == other.period
540+
541+
def __ne__(self, other: Inflation) -> bool:
542+
return not self.__eq__(other)
543+
544+
@property
545+
def period(self) -> datetime.datetime:
546+
""":class:`datetime.datetime`: The time period for the inflation data."""
547+
return datetime.datetime.strptime(self._period, "%b %Y")
548+
549+
def is_monthly_increased(self) -> bool:
550+
""":class:`bool`: Whether the monthly inflation rate increased."""
551+
return self.monthly_rate > 0
552+
553+
def is_yearly_increased(self) -> bool:
554+
""":class:`bool`: Whether the yearly inflation rate increased."""
555+
return self.yearly_rate > 0

apininjas/http.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import sys
2828

2929
import aiohttp
30-
from typing import TYPE_CHECKING, TypeVar, Coroutine, Any, ClassVar, Dict, Optional
30+
from typing import TYPE_CHECKING, TypeVar, Coroutine, Any, ClassVar, Dict, Optional, List
3131

3232
from . import __version__
3333
from .errors import (
@@ -137,3 +137,8 @@ def get_exchange_rate(self, *, pair: str) -> Response[finance.ExchangeRate]:
137137
def get_iban_validation(self, *, iban: str) -> Response[finance.IBANValidation]:
138138
params = {"iban": iban}
139139
return self.request(Route("GET", "/iban"), params=params)
140+
141+
def get_inflation(self, **fields: Any) -> Response[List[finance.Inflation]]:
142+
valid_keys = ("country", "type")
143+
params = {k: v for k, v in fields.items() if k in valid_keys}
144+
return self.request(Route("GET", "/inflation"), params=params)

apininjas/types/finance.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
SOFTWARE.
2323
"""
2424

25-
from typing import TypedDict, List
25+
from typing import TypedDict, List, Literal
2626

2727

2828
class Gold(TypedDict):
@@ -76,3 +76,11 @@ class IBANValidation(TypedDict):
7676
checksum: str
7777
valid: bool
7878
bban: str
79+
80+
81+
class Inflation(TypedDict):
82+
country: str
83+
type: Literal["CPI", "HICP"]
84+
period: str
85+
monthly_rate_pct: float
86+
yearly_rate_pct: float

apininjas/utils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
# fmt: off
3333
__all__ = (
34+
"MISSING",
3435
"from_timestamp",
3536
)
3637
# fmt: on
@@ -39,6 +40,22 @@
3940
T = TypeVar("T")
4041

4142

43+
class _MissingSentinel:
44+
__slots__ = ()
45+
46+
def __eq__(self, other) -> bool:
47+
return False
48+
49+
def __bool__(self) -> bool:
50+
return False
51+
52+
def __repr__(self):
53+
return "..."
54+
55+
56+
MISSING: Any = _MissingSentinel()
57+
58+
4259
def from_timestamp(timestamp: int, /) -> datetime.datetime:
4360
"""A helper function that converts a given timestamp into a :class:`~datetime.datetime` object.
4461

0 commit comments

Comments
 (0)