Skip to content

Commit 5992fa6

Browse files
committed
current and historical api calls work
1 parent af12869 commit 5992fa6

18 files changed

Lines changed: 821 additions & 0 deletions

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
WeatherStackWrapper
2+
---
3+
In development wrapper library for [WeatherStack](https://weatherstack.com/) weather api.

poetry.lock

Lines changed: 204 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[tool.poetry]
2+
name = "weatherstackwrapper"
3+
version = "0.1.0"
4+
description = "Python wrapper for the weather stack api"
5+
authors = ["Darien Moore <LiskIsBest@gmail.com>"]
6+
license = "GPLv3"
7+
readme = "README.md"
8+
9+
[tool.poetry.dependencies]
10+
python = "^3.10.6"
11+
httpx = "^0.23.3"
12+
pydantic = "^1.10.7"
13+
14+
15+
[build-system]
16+
requires = ["poetry-core"]
17+
build-backend = "poetry.core.masonry.api"

weatherstackwrapper/BaseApi.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from .types import Units, Language, Response
2+
from .utility import c_TypeError
3+
4+
5+
class BaseWeatherStackApi:
6+
base_url = "https://api.weatherstack.com/"
7+
8+
def __init__(self, access_key: str):
9+
self.__access_key = access_key
10+
11+
def current(
12+
self, location: str, units: str | Units = None, language: str | Language = None
13+
) -> Response:
14+
params = {"access_key": self.__access_key}
15+
16+
if not isinstance(location, str):
17+
raise c_TypeError(
18+
param_name="location", correct="str", wrong=type(location).__name__
19+
)
20+
params["query"] = location
21+
22+
if units:
23+
if isinstance(units, Units):
24+
units = units.value
25+
elif not isinstance(units, str):
26+
raise c_TypeError(
27+
param_name="units", correct="str", wrong=type(location).__name__
28+
)
29+
params["units"] = units
30+
31+
if language:
32+
if isinstance(language, Language):
33+
language = language.value
34+
elif not isinstance(units, str):
35+
raise c_TypeError(
36+
param_name="units", correct="str", wrong=type(location).__name__
37+
)
38+
params["language"] = language
39+
40+
return {"method": "GET", "url": self.base_url + "current", "params": params}
41+
42+
def historical(
43+
self,
44+
location: str,
45+
historical_date: str,
46+
hourly: bool = None,
47+
interval: int = None,
48+
units: str | Units = None,
49+
language: str | Language = None,
50+
) -> Response:
51+
params = {
52+
"access_key": self.__access_key,
53+
}
54+
55+
if not isinstance(location, str):
56+
raise c_TypeError(
57+
param_name="location", correct="str", wrong=type(location).__name__
58+
)
59+
params["query"] = location
60+
61+
if not isinstance(historical_date, str):
62+
raise c_TypeError(
63+
param_name="historical_date",
64+
correct="str",
65+
wrong=type(location).__name__,
66+
)
67+
params["historical_date"] = historical_date
68+
69+
if hourly:
70+
if not isinstance(hourly, bool):
71+
raise c_TypeError(
72+
param_name=hourly, correct="bool", wrong=type(hourly).__name
73+
)
74+
params["hourly"] = hourly.__int__()
75+
76+
if interval:
77+
if not isinstance(interval, int):
78+
raise c_TypeError(
79+
param_name="interval", correct="int", wrong=type(interval).__name__
80+
)
81+
params["interval"] = interval
82+
83+
if units:
84+
if isinstance(units, Units):
85+
units = units.value
86+
elif not isinstance(units, str):
87+
raise c_TypeError(
88+
param_name="units", correct="str", wrong=type(location).__name__
89+
)
90+
params["units"] = units
91+
92+
if language:
93+
if isinstance(language, Language):
94+
language = language.value
95+
elif not isinstance(units, str):
96+
raise c_TypeError(
97+
param_name="units", correct="str", wrong=type(location).__name__
98+
)
99+
params["language"] = language
100+
101+
return {"method": "GET", "url": self.base_url + "historical", "params": params}

weatherstackwrapper/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import types
2+
from .api import WeatherApi

weatherstackwrapper/api.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import functools
2+
3+
import httpx
4+
from pydantic import parse_obj_as
5+
6+
from .BaseApi import BaseWeatherStackApi
7+
from .types import Error, Response, Units, Language
8+
9+
10+
class WeatherApi(BaseWeatherStackApi):
11+
def __init__(self, access_key: str):
12+
self.Client = httpx.Client(timeout=15.0)
13+
super().__init__(access_key=access_key)
14+
15+
def request(func):
16+
"""non-async http request"""
17+
18+
@functools.wraps(func)
19+
def wrapper(self, *args, **kwargs):
20+
data = func(self, *args, **kwargs)
21+
response = self.Client.request(
22+
method=data["method"],
23+
url=data["url"],
24+
params=data["params"],
25+
).json()
26+
if "success" in response:
27+
return parse_obj_as(type_=Error, obj=response)
28+
return parse_obj_as(type_=Response, obj=response)
29+
30+
return wrapper
31+
32+
@request
33+
def current(
34+
self, location: str, units: str | Units = None, language: str | Language = None
35+
) -> Response:
36+
return super().current(location=location, units=units, language=language)
37+
38+
@request
39+
def historical(
40+
self,
41+
location: str,
42+
historical_date: str,
43+
hourly: bool = None,
44+
interval: int = None,
45+
units: str | Units = None,
46+
language: str | Language = None,
47+
) -> Response:
48+
return super().historical(
49+
location=location,
50+
historical_date=historical_date,
51+
hourly=hourly,
52+
interval=interval,
53+
units=units,
54+
language=language,
55+
)

0 commit comments

Comments
 (0)