Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.6.0 #97

Merged
merged 8 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
# Changelog

## [0.4.3a2](https://github.com/NeonGeckoCom/neon_api_proxy/tree/0.4.3a2) (2024-02-26)
## [0.6.0](https://github.com/NeonGeckoCom/neon_api_proxy/tree/0.6.0) (2024-06-17)

[Full Changelog](https://github.com/NeonGeckoCom/neon_api_proxy/compare/0.4.3a1...0.4.3a2)
[Full Changelog](https://github.com/NeonGeckoCom/neon_api_proxy/compare/0.5.1a3...0.6.0)

**Implemented enhancements:**

- \[FEAT\] Add Daily and Hourly Weather API calls [\#71](https://github.com/NeonGeckoCom/neon_api_proxy/issues/71)
- Handle requests for unauthenticated APIs [\#21](https://github.com/NeonGeckoCom/neon_api_proxy/issues/21)

## [0.5.1a3](https://github.com/NeonGeckoCom/neon_api_proxy/tree/0.5.1a3) (2024-05-07)

[Full Changelog](https://github.com/NeonGeckoCom/neon_api_proxy/compare/0.5.1a2...0.5.1a3)

**Merged pull requests:**

- Update W|A and OWM wrappers to match upstream APIs [\#96](https://github.com/NeonGeckoCom/neon_api_proxy/pull/96) ([NeonDaniel](https://github.com/NeonDaniel))

## [0.5.1a2](https://github.com/NeonGeckoCom/neon_api_proxy/tree/0.5.1a2) (2024-04-25)

[Full Changelog](https://github.com/NeonGeckoCom/neon_api_proxy/compare/0.5.1a1...0.5.1a2)

**Merged pull requests:**

- Update geolocation tests [\#91](https://github.com/NeonGeckoCom/neon_api_proxy/pull/91) ([NeonDaniel](https://github.com/NeonDaniel))
- feat: allow ovos-utils 0.1.0 [\#94](https://github.com/NeonGeckoCom/neon_api_proxy/pull/94) ([mikejgray](https://github.com/mikejgray))

## [0.4.3a1](https://github.com/NeonGeckoCom/neon_api_proxy/tree/0.4.3a1) (2023-12-28)
## [0.5.1a1](https://github.com/NeonGeckoCom/neon_api_proxy/tree/0.5.1a1) (2024-04-09)

[Full Changelog](https://github.com/NeonGeckoCom/neon_api_proxy/compare/0.4.2...0.4.3a1)
[Full Changelog](https://github.com/NeonGeckoCom/neon_api_proxy/compare/0.5.0...0.5.1a1)

**Merged pull requests:**

- Add Map Maker API with unit tests [\#88](https://github.com/NeonGeckoCom/neon_api_proxy/pull/88) ([NeonDaniel](https://github.com/NeonDaniel))
- OWM language handling [\#93](https://github.com/NeonGeckoCom/neon_api_proxy/pull/93) ([NeonDaniel](https://github.com/NeonDaniel))



Expand Down
6 changes: 3 additions & 3 deletions neon_api_proxy/api_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ def handle_api_input(self,
LOG.info(f"request={request}")

respond = self.proxy.resolve_query(request)
LOG.info(f"message={message_id} "
f"status={respond.get('status_code')}")
LOG.debug(f"response message={message_id} "
f"status={respond.get('status_code')}")

try:
respond['content'] = bytes(respond.get('content', b'')).\
Expand Down Expand Up @@ -121,7 +121,7 @@ def extract_agent_tokens(msg_data: dict) -> dict:
tokens['message_id'] = tokens['replied_message'] = \
msg_data.get('messageID', None)
else:
LOG.warning('Failed to resolve an agent from the message data')
LOG.debug('No valid agent specified in the message data')
return tokens

def handle_error(self, thread, exception):
Expand Down
3 changes: 3 additions & 0 deletions neon_api_proxy/client/open_weather_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ def _make_api_call(lat: Union[str, float], lng: Union[str, float],
except JSONDecodeError:
data = {"error": "Error decoding response",
"response": resp}
if data.get('cod') == "400":
# Backwards-compat. Put error response under `error` key
data["error"] = data.get("message")
if data.get('cod'):
data['cod'] = str(data['cod'])
# TODO: Handle failures
Expand Down
5 changes: 3 additions & 2 deletions neon_api_proxy/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ def init_service_instances(self, service_class_mapping: dict) -> dict:
api_key = self.config.get(item, {}).get("api_key") if self.config \
else None
try:
if api_key is None:
LOG.warning(f"No API key for {item} in {self.config}")
if api_key is None and item != 'api_test_endpoint':
LOG.warning(f"No API key for {item} in "
f"{list(self.config.keys())}")
service_mapping[item] = \
service_class_mapping[item](api_key=api_key)
except Exception as e:
Expand Down
26 changes: 18 additions & 8 deletions neon_api_proxy/services/owm_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from requests import Response

from neon_api_proxy.cached_api import CachedAPI
from ovos_utils.log import LOG
from ovos_utils.log import LOG, log_deprecation
from neon_utils.authentication_utils import find_neon_owm_key


Expand Down Expand Up @@ -60,35 +60,45 @@ def handle_query(self, **kwargs) -> dict:
lat = kwargs.get("lat")
lng = kwargs.get("lng", kwargs.get("lon"))
api = kwargs.get('api') or "onecall"
lang = kwargs.get('lang') or "en"
units = "metric" if kwargs.get("units") == "metric" else "imperial"

if not all((lat, lng, units)):
return {"status_code": -1,
"content": f"Missing required args in: {kwargs}",
"encoding": None}
try:
resp = self._get_api_response(lat, lng, units, api)
resp = self._get_api_response(lat, lng, units, api, lang)
except Exception as e:
return {"status_code": -1,
"content": repr(e),
"encoding": None}
if not resp.ok:
LOG.error(f"Bad response code: {resp.status_code}")
LOG.error(f"Bad response code: {resp.status_code}: "
f"content={resp.content}")
return {"status_code": resp.status_code,
"content": resp.content,
"encoding": resp.encoding}

def _get_api_response(self, lat: str, lng: str, units: str,
api: str = "onecall") -> Response:
str(float(lat))
str(float(lng))
api: str = "onecall", lang: str = "en") -> Response:
try:
assert isinstance(float(lat), float), f"Invalid latitude: {lat}"
assert isinstance(float(lng), float), f"Invalid longitude: {lng}"
except AssertionError as e:
raise ValueError(e)
if api != "onecall":
log_deprecation(f"{api} was requested but only `onecall` "
f"is supported", "1.0.0")
api = "onecall"
assert units in ("metric", "imperial", "standard")
query_params = {"lat": lat,
"lon": lng,
"appid": self._api_key,
"units": units}
"units": units,
"lang": lang}
query_str = urllib.parse.urlencode(query_params)
base_url = "http://api.openweathermap.org/data/2.5"
base_url = "http://api.openweathermap.org/data/3.0"
resp = self.get_with_cache_timeout(f"{base_url}/{api}?{query_str}",
self.cache_timeout)
return resp
3 changes: 2 additions & 1 deletion neon_api_proxy/services/wolfram_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def _build_query_string(**kwargs) -> str:
query_params = dict()
query_params['i'] = kwargs.get("query")
query_params['units'] = kwargs.get("units") if \
kwargs.get("units") == "metric" else "nonmetric"
kwargs.get("units") == "metric" else "imperial"
lat = kwargs.get("lat")
lng = kwargs.get("lng")
if kwargs.get("latlong"):
Expand Down Expand Up @@ -156,6 +156,7 @@ def _query_api(self, query: str) -> dict:
:return: dict response containing:
`status_code`, `content`, and `encoding`
"""
LOG.debug(f"query={query}")
result = self.get_with_cache_timeout(query, timeout=self.cache_time)
if not result.ok:
# 501 = Wolfram couldn't understand
Expand Down
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
requests-cache~=0.6,>=0.6.4
requests~=2.20
neon_utils[network]~=1.0
ovos-utils~=0.0.31
ovos-utils>=0.0.31,<0.2.0
ovos-config~=0.0.10
neon-mq-connector~=0.7
7 changes: 7 additions & 0 deletions tests/test_owm_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ def test_handle_query_valid_onecall(self):
self.assertEqual(resp["encoding"], "utf-8")
self.assertIsInstance(json.loads(resp["content"]), dict)

spanish = self.api.handle_query(**VALID_QUERY_ONECALL, lang="es")
self.assertIsInstance(spanish, dict)
self.assertEqual(spanish["status_code"], 200)
self.assertEqual(spanish["encoding"], "utf-8")
self.assertIsInstance(json.loads(spanish["content"]), dict)
self.assertNotEqual(spanish, resp)

def test_handle_query_valid_current(self):
resp = self.api.handle_query(**VALID_QUERY_CURRENT)
self.assertIsInstance(resp, dict)
Expand Down
10 changes: 5 additions & 5 deletions tests/test_wolfram_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@
"ip": "50.47.129.133"}

VALID_QUERY_LAT_LON = {"query": "how far away is new york?",
"units": "nonmetric",
"units": "imperial",
"lat": "47.4797",
"lng": "122.2079"}

VALID_QUERY_LAT_LON_IP = {"query": "how far away is Bellevue?",
"units": "nonmetric",
"units": "nonmetric", # Test backwards-compat.
"lat": "47.4797",
"lng": "122.2079",
"ip": "50.47.129.133"}
Expand Down Expand Up @@ -86,19 +86,19 @@ def test_build_query_url_invalid_param_types(self):

def test_build_query_string_valid_minimal(self):
query_str = self.api._build_query_string(**VALID_QUERY_MINIMAL)
self.assertEqual(query_str, f"i=how+far+away+is+Miami%3F&units=nonmetric")
self.assertEqual(query_str, f"i=how+far+away+is+Miami%3F&units=imperial")

def test_build_query_string_valid_lat_lng(self):
query_str = self.api._build_query_string(**VALID_QUERY_LAT_LON)
self.assertEqual(query_str, f"i=how+far+away+is+new+york%3F&units=nonmetric&latlong=47.4797%2C122.2079")
self.assertEqual(query_str, f"i=how+far+away+is+new+york%3F&units=imperial&latlong=47.4797%2C122.2079")

def test_build_query_string_valid_ip(self):
query_str = self.api._build_query_string(**VALID_QUERY_IP)
self.assertEqual(query_str, f"i=how+far+away+is+Moscow%3F&units=metric&ip=50.47.129.133")

def test_build_query_string_valid_lat_lng_ip(self):
query_str = self.api._build_query_string(**VALID_QUERY_LAT_LON_IP)
self.assertEqual(query_str, f"i=how+far+away+is+Bellevue%3F&units=nonmetric&latlong=47.4797%2C122.2079")
self.assertEqual(query_str, f"i=how+far+away+is+Bellevue%3F&units=imperial&latlong=47.4797%2C122.2079")

def test_build_query_invalid_query(self):
with self.assertRaises(ValueError):
Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

__version__ = "0.5.0"
__version__ = "0.6.0"
Loading