Skip to content

Commit

Permalink
fix 502 error
Browse files Browse the repository at this point in the history
  • Loading branch information
François AIZPURU authored and Quentame committed Nov 29, 2023
1 parent e46665b commit 2f13296
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 68 deletions.
13 changes: 7 additions & 6 deletions src/meteofrance_api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,19 +231,18 @@ def get_warning_current_phenomenoms(
# Send the API request
resp = self.session.request(
"get",
"warning/currentphenomenons",
"v3/warning/currentphenomenons",
params={"domain": domain, "depth": depth},
)

# Create object with API response
phenomenoms = CurrentPhenomenons(resp.json())

# if user ask to have the coastal bulletin merged
if with_costal_bulletin:
if domain in COASTAL_DEPARTMENT_LIST:
resp = self.session.request(
"get",
"warning/currentphenomenons",
"v3/warning/currentphenomenons",
params={"domain": domain + "10"},
)
phenomenoms.merge_with_coastal_phenomenons(
Expand Down Expand Up @@ -272,7 +271,9 @@ def get_warning_full(self, domain: str, with_costal_bulletin: bool = False) -> F
# TODO: add formatDate parameter

# Send the API request
resp = self.session.request("get", "warning/full", params={"domain": domain})
resp = self.session.request(
"get", "/v3/warning/full", params={"domain": domain}
)

# Create object with API response
full_phenomenoms = Full(resp.json())
Expand All @@ -282,7 +283,7 @@ def get_warning_full(self, domain: str, with_costal_bulletin: bool = False) -> F
if domain in COASTAL_DEPARTMENT_LIST:
resp = self.session.request(
"get",
"warning/full",
"v3/warning/full",
params={"domain": domain + "10"},
)
full_phenomenoms.merge_with_coastal_phenomenons(Full(resp.json()))
Expand All @@ -301,7 +302,7 @@ def get_warning_thumbnail(self, domain: str = "france") -> str:
"""
# Return directly the URL of the gif image
return (
f"{METEOFRANCE_API_URL}/warning/thumbnail?&token={METEOFRANCE_API_TOKEN}"
f"{METEOFRANCE_API_URL}/v3/warning/thumbnail?&token={METEOFRANCE_API_TOKEN}"
f"&domain={domain}"
)

Expand Down
48 changes: 24 additions & 24 deletions src/meteofrance_api/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,31 @@
ALERT_COLOR_LIST_EN = [None, "Green", "Yellow", "Orange", "Red"]

# Weather alert type
ALERT_TYPE_LIST_FR = [
None,
"Vent violent",
"Pluie-inondation",
"Orages",
"Inondation",
"Neige-verglas",
"Canicule",
"Grand-froid",
"Avalanches",
"Vagues-submersion",
]
ALERT_TYPE_DICTIONARY_FR = {
"0": None,
"1": "Vent violent",
"2": "Pluie-inondation",
"3": "Orages",
"4": "Inondation",
"5": "Neige-verglas",
"6": "Canicule",
"7": "Grand-froid",
"8": "Avalanches",
"9": "Vagues-submersion",
}

ALERT_TYPE_LIST_EN = [
None,
"Wind",
"Rain-Flood",
"Thunderstorms",
"Flood",
"Snow/Ice",
"Extreme high temperature",
"Extreme low temperature",
"Avalanches",
"Coastal Event",
]
ALERT_TYPE_DICTIONARY_EN = {
"0": None,
"1": "Wind",
"2": "Rain-Flood",
"3": "Thunderstorms",
"4": "Flood",
"5": "Snow/Ice",
"6": "Extreme high temperature",
"7": "Extreme low temperature",
"8": "Avalanches",
"9": "Coastal Event",
}


# Valide departments list for weather alert bulletin
Expand Down
13 changes: 7 additions & 6 deletions src/meteofrance_api/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@

from .const import ALERT_COLOR_LIST_EN
from .const import ALERT_COLOR_LIST_FR
from .const import ALERT_TYPE_LIST_EN
from .const import ALERT_TYPE_LIST_FR
from .const import ALERT_TYPE_DICTIONARY_EN
from .const import ALERT_TYPE_DICTIONARY_FR
from .const import COASTAL_DEPARTMENT_LIST
from .const import VALID_DEPARTMENT_LIST
from .model.place import Place
from .model.warning import PhenomenonMaxColor


def get_warning_text_status_from_indice_color(
Expand All @@ -39,7 +40,7 @@ def get_warning_text_status_from_indice_color(


def get_phenomenon_name_from_indice(
int_phenomenon: int, lang: str = "fr"
int_phenomenon: str, lang: str = "fr"
) -> Optional[str]:
"""Convert the phenomenom code in readable text (Hepler).
Expand All @@ -52,9 +53,9 @@ def get_phenomenon_name_from_indice(
Phenomenom in text. French or English according to the lang parameter.
"""
if lang == "fr":
return ALERT_TYPE_LIST_FR[int_phenomenon]
return ALERT_TYPE_DICTIONARY_FR[int_phenomenon]

return ALERT_TYPE_LIST_EN[int_phenomenon]
return ALERT_TYPE_DICTIONARY_EN[int_phenomenon]


def is_coastal_department(department_number: str) -> bool:
Expand Down Expand Up @@ -84,7 +85,7 @@ def is_valid_warning_department(department_number: str) -> bool:


def readeable_phenomenoms_dict(
list_phenomenoms: List[Dict[str, int]], language: str = "fr"
list_phenomenoms: List[PhenomenonMaxColor], language: str = "fr"
) -> Dict[Optional[str], Optional[str]]:
"""Create a dictionary with human readable keys and values (Helper).
Expand Down
30 changes: 26 additions & 4 deletions src/meteofrance_api/model/warning.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,35 @@
from typing import TypedDict


# Define a custom type for items in the phenomenons_max_colors list
class PhenomenonMaxColor(TypedDict):
"""A type definition for representing a meteorological phenomenon and its maximum color code.
Attributes:
phenomenon_id (str): A unique identifier for the meteorological phenomenon.
This is kept as a string to match the format provided by
the API and could represent various types of weather
phenomena (e.g., storms, heavy rain, etc.).
phenomenon_max_color_id (int): An integer representing the maximum alert color
code associated with the phenomenon. The color
codes typically indicate the severity or urgency
of the weather-related alerts or warnings, with
each color corresponding to a specific level of
alert.
"""

phenomenon_id: str
phenomenon_max_color_id: int


class WarnningCurrentPhenomenonsData(TypedDict):
"""Describing the data structure of CurrentPhenomenons object from the REST API."""

update_time: int
end_validity_time: int
domain_id: str
phenomenons_max_colors: List[Dict[str, int]]
phenomenons_max_colors: List[PhenomenonMaxColor]


class WarnningFullData(TypedDict):
Expand All @@ -27,7 +49,7 @@ class WarnningFullData(TypedDict):
domain_id: str
color_max: int
timelaps: List[Dict[str, Any]]
phenomenons_items: List[Dict[str, int]]
phenomenons_items: List[PhenomenonMaxColor]
advices: Optional[List[Dict[str, Any]]]
consequences: Optional[List[Dict[str, Any]]]
max_count_items: Any # Didn't see any value yet
Expand Down Expand Up @@ -79,7 +101,7 @@ def domain_id(self) -> str:
return self.raw_data["domain_id"]

@property
def phenomenons_max_colors(self) -> List[Dict[str, int]]:
def phenomenons_max_colors(self) -> List[PhenomenonMaxColor]:
"""Return the list and colors of the phenomenoms."""
return self.raw_data["phenomenons_max_colors"]

Expand Down Expand Up @@ -171,7 +193,7 @@ def timelaps(self) -> List[Dict[str, Any]]:
return self.raw_data["timelaps"]

@property
def phenomenons_items(self) -> List[Dict[str, int]]:
def phenomenons_items(self) -> List[PhenomenonMaxColor]:
"""Return the phenomenom list of the domain."""
return self.raw_data["phenomenons_items"]

Expand Down
16 changes: 9 additions & 7 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@
from meteofrance_api.helpers import sort_places_versus_distance_from_coordinates
from meteofrance_api.model import Place
from meteofrance_api.model.place import PlaceData
from meteofrance_api.model.warning import PhenomenonMaxColor


def test_text_helpers_fr() -> None:
"""Test helpers to have readable alert type and alert level in French."""
assert get_warning_text_status_from_indice_color(1) == "Vert"
assert get_phenomenon_name_from_indice(2) == "Pluie-inondation"
assert get_phenomenon_name_from_indice("2") == "Pluie-inondation"


def test_get_warning_text_status_from_indice_color_en() -> None:
"""Test helpers to have readable alert type and alert level in English."""
assert get_warning_text_status_from_indice_color(4, "en") == "Red"
assert get_phenomenon_name_from_indice(4, "en") == "Flood"
assert get_phenomenon_name_from_indice("4", "en") == "Flood"


@pytest.mark.parametrize("dep, res", [("03", False), ("06", True), ("2B", True)])
Expand All @@ -43,12 +44,13 @@ def test_is_valid_warning_department(dep: str, res: bool) -> None:
def test_readeable_phenomenoms_dict() -> None:
"""Test the helper constructing a human readable dictionary for phenomenom."""
api_list = [
{"phenomenon_id": 4, "phenomenon_max_color_id": 1},
{"phenomenon_id": 5, "phenomenon_max_color_id": 1},
{"phenomenon_id": 3, "phenomenon_max_color_id": 2},
{"phenomenon_id": 2, "phenomenon_max_color_id": 1},
{"phenomenon_id": 1, "phenomenon_max_color_id": 3},
PhenomenonMaxColor(phenomenon_id="4", phenomenon_max_color_id=1),
PhenomenonMaxColor(phenomenon_id="5", phenomenon_max_color_id=1),
PhenomenonMaxColor(phenomenon_id="3", phenomenon_max_color_id=2),
PhenomenonMaxColor(phenomenon_id="2", phenomenon_max_color_id=1),
PhenomenonMaxColor(phenomenon_id="1", phenomenon_max_color_id=3),
]

expected_dictionary = {
"Inondation": "Vert",
"Neige-verglas": "Vert",
Expand Down
1 change: 0 additions & 1 deletion tests/test_integrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from meteofrance_api.helpers import readeable_phenomenoms_dict


@pytest.mark.skip(reason="Returns 502 Server Error: Bad Gateway from summer 2023")
@pytest.mark.parametrize("city", ["montreal", "Foix"])
def test_workflow(city: str) -> None:
"""Test classical workflow usage with the Python library."""
Expand Down
12 changes: 6 additions & 6 deletions tests/test_picture_of_the_day.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# coding: utf-8
"""Tests Météo-France module. PictureOfTheDay class."""
from meteofrance_api import const
from meteofrance_api import MeteoFranceClient


Expand All @@ -10,9 +11,8 @@ def test_picture_of_the_day() -> None:
potd = client.get_picture_of_the_day()

assert potd.description
assert potd.image_url == (
"https://webservice.meteofrance.com/v2/report"
"?domain=france&report_type=observation"
"&report_subtype=image%20du%20jour&format=jpg"
"&token=__Wj7dVSTjV9YGu1guveLyDq0g7S7TfTjaHBTPTpO0kj8__"
)
params = "?domain=france&report_type=observation&report_subtype=image%20du%20jour&format=jpg"
token_param = f"&token={const.METEOFRANCE_API_TOKEN}"
path = "/v2/report"
assert_url = f"{const.METEOFRANCE_API_URL}{path}{params}{token_param}"
assert potd.image_url == assert_url
24 changes: 10 additions & 14 deletions tests/test_warning.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,24 @@
WARNING_COLOR_LIST = [1, 2, 3, 4]


@pytest.mark.skip(reason="Returns 502 Server Error: Bad Gateway from summer 2023")
def test_currentphenomenons(requests_mock: Mock) -> None:
"""Test basic weather alert results from API."""
client = MeteoFranceClient()

requests_mock.request(
"get",
f"{METEOFRANCE_API_URL}/warning/currentphenomenons",
f"{METEOFRANCE_API_URL}/v3/warning/currentphenomenons",
json={
"update_time": 1591279200,
"end_validity_time": 1591365600,
"domain_id": "32",
"phenomenons_max_colors": [
{"phenomenon_id": 6, "phenomenon_max_color_id": 1},
{"phenomenon_id": 4, "phenomenon_max_color_id": 1},
{"phenomenon_id": 5, "phenomenon_max_color_id": 3},
{"phenomenon_id": 2, "phenomenon_max_color_id": 1},
{"phenomenon_id": 1, "phenomenon_max_color_id": 1},
{"phenomenon_id": 3, "phenomenon_max_color_id": 2},
{"phenomenon_id": "6", "phenomenon_max_color_id": 1},
{"phenomenon_id": "4", "phenomenon_max_color_id": 1},
{"phenomenon_id": "5", "phenomenon_max_color_id": 3},
{"phenomenon_id": "2", "phenomenon_max_color_id": 1},
{"phenomenon_id": "1", "phenomenon_max_color_id": 1},
{"phenomenon_id": "3", "phenomenon_max_color_id": 2},
],
},
)
Expand All @@ -42,7 +41,6 @@ def test_currentphenomenons(requests_mock: Mock) -> None:
assert current_phenomenoms.get_domain_max_color() == 3


@pytest.mark.skip(reason="Returns 502 Server Error: Bad Gateway from summer 2023")
def test_fulls() -> None:
"""Test advanced weather alert results from API."""
client = MeteoFranceClient()
Expand Down Expand Up @@ -70,13 +68,12 @@ def test_thumbnail() -> None:
thumbnail_url = client.get_warning_thumbnail()

assert thumbnail_url == (
"https://webservice.meteofrance.com/warning/thumbnail"
"https://webservice.meteofrance.com/v3/warning/thumbnail"
"?&token=__Wj7dVSTjV9YGu1guveLyDq0g7S7TfTjaHBTPTpO0kj8__&"
"domain=france"
)


@pytest.mark.skip(reason="Returns 502 Server Error: Bad Gateway from summer 2023")
@pytest.mark.parametrize("dep, res", [("13", True), ("32", False)])
def test_currentphenomenons_with_coastal_bulletin(dep: str, res: bool) -> None:
"""Test getting a complete basic bulletin for coastal department."""
Expand All @@ -86,13 +83,12 @@ def test_currentphenomenons_with_coastal_bulletin(dep: str, res: bool) -> None:
domain=dep, depth=1, with_costal_bulletin=True
)
has_coastal_phenomenom = any(
phenomenom["phenomenon_id"] == 9
phenomenom["phenomenon_id"] == "9"
for phenomenom in current_phenomenoms.phenomenons_max_colors
)
assert has_coastal_phenomenom == res


@pytest.mark.skip(reason="Returns 502 Server Error: Bad Gateway from summer 2023")
@pytest.mark.parametrize("dep, res", [("13", True), ("32", False)])
def test_full_with_coastal_bulletint(dep: str, res: bool) -> None:
"""Test getting a complete advanced bulletin for coastal department."""
Expand All @@ -101,7 +97,7 @@ def test_full_with_coastal_bulletint(dep: str, res: bool) -> None:
full_phenomenoms = client.get_warning_full(domain=dep, with_costal_bulletin=True)

has_coastal_phenomenom = any(
phenomenom["phenomenon_id"] == 9
phenomenom["phenomenon_id"] == "9"
for phenomenom in full_phenomenoms.phenomenons_items
)
assert has_coastal_phenomenom == res

0 comments on commit 2f13296

Please sign in to comment.