meteocatpy 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/filetree.txt +8 -0
- package/meteocatpy/alerts.py +111 -0
- package/meteocatpy/const.py +3 -0
- package/meteocatpy/data.py +27 -2
- package/meteocatpy/infostation.py +63 -0
- package/meteocatpy/quotes.py +71 -0
- package/meteocatpy/version.py +1 -1
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/setup.cfg +2 -1
- package/tests/integration_test_alerts.py +39 -0
- package/tests/integration_test_infostation.py +34 -0
- package/tests/integration_test_quotes.py +32 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
## [0.0.18](https://github.com/figorr/meteocatpy/compare/v0.0.17...v0.0.18) (2025-01-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* 0.0.18 ([bdc81d2](https://github.com/figorr/meteocatpy/commit/bdc81d2c4ada74478e66d376962bd2e7b01fe39b))
|
|
7
|
+
* 0.0.19 ([2884a6f](https://github.com/figorr/meteocatpy/commit/2884a6ff7216f412e5144ba8a89a300f6b0a42c2))
|
|
8
|
+
* fix error variable null ([cba0f9d](https://github.com/figorr/meteocatpy/commit/cba0f9d80c1b2a6e6f3ab8660b7ae703bfe4c148))
|
|
9
|
+
* fix timedelta ([dc716ad](https://github.com/figorr/meteocatpy/commit/dc716ad3843f1e138ccab6ac7e01d406e13cf4a5))
|
|
10
|
+
|
|
11
|
+
## [0.0.17](https://github.com/figorr/meteocatpy/compare/v0.0.16...v0.0.17) (2024-12-29)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* 0.0.17 ([ea316af](https://github.com/figorr/meteocatpy/commit/ea316aff268970420dce1c7337d8e7b45859f13c))
|
|
17
|
+
* add alerts feature request ([b5f664c](https://github.com/figorr/meteocatpy/commit/b5f664c2b305130bf55cd9a88ac2c007443e1f67))
|
|
18
|
+
* add alerts test ([72a95a6](https://github.com/figorr/meteocatpy/commit/72a95a66f39908831255c06a6361512c3efcaffb))
|
|
19
|
+
* add alerts url ([1a61bdb](https://github.com/figorr/meteocatpy/commit/1a61bdbe919c45239278d80471d003660ffb53e8))
|
|
20
|
+
* add info station url ([759f0db](https://github.com/figorr/meteocatpy/commit/759f0db95dcc00c8a99d269cdce1eadc7dfe4284))
|
|
21
|
+
* add infostation feature request ([d30ec37](https://github.com/figorr/meteocatpy/commit/d30ec3796e4be27a2601abdbb7c1c50ada8fa485))
|
|
22
|
+
* add quotes feature request ([012fba3](https://github.com/figorr/meteocatpy/commit/012fba30febd6ac76c46ac684ff2f5f25f520acd))
|
|
23
|
+
* add quotes url ([27950fb](https://github.com/figorr/meteocatpy/commit/27950fbf3eb488566e2f5955cb7b8a53a63a77ee))
|
|
24
|
+
* fix alerts test ([742a70e](https://github.com/figorr/meteocatpy/commit/742a70ed584dcc6febb66a3c1b9a3b85574ebd18))
|
|
25
|
+
* fix description ([b41fe6a](https://github.com/figorr/meteocatpy/commit/b41fe6a23385d5fe0e445ad8453bf94ae4cdd623))
|
|
26
|
+
* fix python version from 3.7 to 3.12 and asyncio_default_fixture_loop_scope ([08a8f2e](https://github.com/figorr/meteocatpy/commit/08a8f2ed5a6768f7aa01e2d9959372bc756e501c))
|
|
27
|
+
* ignore alerts json file ([68abbf3](https://github.com/figorr/meteocatpy/commit/68abbf3bb20d4fdfadaf55c8774dec29aa699bcd))
|
|
28
|
+
* new repo file structure ([a6d62b8](https://github.com/figorr/meteocatpy/commit/a6d62b8acca9cadaff96fc1631f71903e2925479))
|
|
29
|
+
|
|
1
30
|
## [0.0.16](https://github.com/figorr/meteocatpy/compare/v0.0.15...v0.0.16) (2024-12-28)
|
|
2
31
|
|
|
3
32
|
|
package/filetree.txt
CHANGED
|
@@ -15,16 +15,20 @@
|
|
|
15
15
|
└── meteocatpy/
|
|
16
16
|
├── README.md
|
|
17
17
|
├── __init__.py
|
|
18
|
+
├── alerts.py
|
|
18
19
|
├── const.py
|
|
19
20
|
├── data.py
|
|
20
21
|
├── exceptions.py
|
|
21
22
|
├── forecast.py
|
|
22
23
|
├── helpers.py
|
|
24
|
+
├── infostation.py
|
|
23
25
|
├── py.typed
|
|
26
|
+
├── quotes.py
|
|
24
27
|
├── stations.py
|
|
25
28
|
├── symbols.py
|
|
26
29
|
├── town.py
|
|
27
30
|
├── townstations.py
|
|
31
|
+
├── uvi.py
|
|
28
32
|
├── variables.py
|
|
29
33
|
├── version.py
|
|
30
34
|
├── package-lock.json
|
|
@@ -38,11 +42,15 @@
|
|
|
38
42
|
└── tests/
|
|
39
43
|
├── data_test.py
|
|
40
44
|
├── import_test.py
|
|
45
|
+
├── integration_test_alerts.py
|
|
41
46
|
├── integration_test_complete.py
|
|
42
47
|
├── integration_test_forecast.py
|
|
48
|
+
├── integration_test_infostation.py
|
|
49
|
+
├── integration_test_quotes.py
|
|
43
50
|
├── integration_test_station_data.py
|
|
44
51
|
├── integration_test_stations.py
|
|
45
52
|
├── integration_test_symbols.py
|
|
46
53
|
├── integration_test_town.py
|
|
47
54
|
├── integration_test_town_stations.py
|
|
55
|
+
├── integration_test_uvi.py
|
|
48
56
|
├── integration_test_variables.py
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import aiohttp
|
|
2
|
+
import logging
|
|
3
|
+
import re
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from .const import BASE_URL, ALERTS_URL
|
|
6
|
+
from .exceptions import (
|
|
7
|
+
BadRequestError,
|
|
8
|
+
ForbiddenError,
|
|
9
|
+
TooManyRequestsError,
|
|
10
|
+
InternalServerError,
|
|
11
|
+
UnknownAPIError,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
_LOGGER = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
class MeteocatAlerts:
|
|
17
|
+
"""Clase para interactuar con los datos de estaciones de la API de Meteocat."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, api_key: str):
|
|
20
|
+
"""
|
|
21
|
+
Inicializa la clase MeteocatAlerts.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
api_key (str): Clave de API para autenticar las solicitudes.
|
|
25
|
+
"""
|
|
26
|
+
self.api_key = api_key
|
|
27
|
+
self.headers = {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
"X-Api-Key": self.api_key,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def get_current_date():
|
|
34
|
+
"""
|
|
35
|
+
Obtiene la fecha actual en formato numérico.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
tuple: Año (YYYY), mes (MM), día (DD) como enteros.
|
|
39
|
+
"""
|
|
40
|
+
now = datetime.now()
|
|
41
|
+
return now.year, now.month, now.day
|
|
42
|
+
|
|
43
|
+
async def get_alerts(self):
|
|
44
|
+
"""
|
|
45
|
+
Obtiene los datos meteorológicos de alertas desde la API de Meteocat.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
any (str): Año de la consulta.
|
|
49
|
+
mes (str): Mes de la consulta.
|
|
50
|
+
dia (str): Día de la consulta.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
dict: Datos de alertas meteorológicas.
|
|
54
|
+
"""
|
|
55
|
+
any, mes, dia = self.get_current_date() # Calcula la fecha actual
|
|
56
|
+
url = f"{BASE_URL}{ALERTS_URL}".format(
|
|
57
|
+
any=any, mes=f"{mes:02d}", dia=f"{dia:02d}"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
async with aiohttp.ClientSession() as session:
|
|
61
|
+
try:
|
|
62
|
+
async with session.get(url, headers=self.headers) as response:
|
|
63
|
+
if response.status == 200:
|
|
64
|
+
return await response.json()
|
|
65
|
+
|
|
66
|
+
# Gestionar errores según el código de estado
|
|
67
|
+
if response.status == 400:
|
|
68
|
+
error_data = await response.json()
|
|
69
|
+
# Intentar extraer la última fecha válida del mensaje de error
|
|
70
|
+
if "message" in error_data:
|
|
71
|
+
match = re.search(r'entre (\d{2}-\d{2}-\d{4}) i', error_data["message"])
|
|
72
|
+
if match:
|
|
73
|
+
last_valid_date = match.group(1) # Captura la última fecha válida
|
|
74
|
+
dia, mes, any = map(int, last_valid_date.split('-'))
|
|
75
|
+
# Intentar nuevamente con la última fecha válida
|
|
76
|
+
new_url = f"{BASE_URL}{ALERTS_URL}".format(
|
|
77
|
+
any=any, mes=f"{mes:02d}", dia=f"{dia:02d}"
|
|
78
|
+
)
|
|
79
|
+
async with session.get(new_url, headers=self.headers) as new_response:
|
|
80
|
+
if new_response.status == 200:
|
|
81
|
+
return await new_response.json()
|
|
82
|
+
raise UnknownAPIError(
|
|
83
|
+
f"Failed with the valid date {last_valid_date}: {await new_response.text()}"
|
|
84
|
+
)
|
|
85
|
+
raise BadRequestError(await response.json())
|
|
86
|
+
elif response.status == 403:
|
|
87
|
+
error_data = await response.json()
|
|
88
|
+
if error_data.get("message") == "Forbidden":
|
|
89
|
+
raise ForbiddenError(error_data)
|
|
90
|
+
elif error_data.get("message") == "Missing Authentication Token":
|
|
91
|
+
raise ForbiddenError(error_data)
|
|
92
|
+
elif response.status == 429:
|
|
93
|
+
raise TooManyRequestsError(await response.json())
|
|
94
|
+
elif response.status == 500:
|
|
95
|
+
raise InternalServerError(await response.json())
|
|
96
|
+
else:
|
|
97
|
+
raise UnknownAPIError(
|
|
98
|
+
f"Unexpected error {response.status}: {await response.text()}"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
except aiohttp.ClientError as e:
|
|
102
|
+
raise UnknownAPIError(
|
|
103
|
+
message=f"Error al conectar con la API de Meteocat: {str(e)}",
|
|
104
|
+
status_code=0,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
except Exception as ex:
|
|
108
|
+
raise UnknownAPIError(
|
|
109
|
+
message=f"Error inesperado: {str(ex)}",
|
|
110
|
+
status_code=0,
|
|
111
|
+
)
|
package/meteocatpy/const.py
CHANGED
|
@@ -4,8 +4,11 @@ MUNICIPIS_LIST_URL = "/referencia/v1/municipis"
|
|
|
4
4
|
MUNICIPIS_HORA_URL = "/pronostic/v1/municipalHoraria/{codi}"
|
|
5
5
|
MUNICIPIS_DIA_URL = "/pronostic/v1/municipal/{codi}"
|
|
6
6
|
SYMBOLS_URL = "/referencia/v1/simbols"
|
|
7
|
+
QUOTES_URL = "/quotes/v1/consum-actual"
|
|
7
8
|
STATIONS_LIST_URL = "/xema/v1/estacions/metadades"
|
|
9
|
+
INFO_STATION_URL = "/xema/v1/estacions/{codi_estacio}/metadades"
|
|
8
10
|
STATIONS_MUNICIPI_URL = "/xema/v1/representatives/metadades/municipis/{codi_municipi}/variables/{codi_variable}"
|
|
9
11
|
VARIABLES_URL = "/xema/v1/variables/mesurades/metadades"
|
|
10
12
|
STATION_DATA_URL = "/xema/v1/estacions/mesurades/{codiEstacio}/{any}/{mes}/{dia}"
|
|
11
13
|
UVI_DATA_URL = "/pronostic/v1/uvi/{codi_municipi}"
|
|
14
|
+
ALERTS_URL = "/pronostic/v2/smp/episodis-oberts?data={any}-{mes}-{dia}Z"
|
package/meteocatpy/data.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import aiohttp
|
|
2
2
|
import logging
|
|
3
3
|
import re
|
|
4
|
-
from datetime import datetime
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
5
|
from .variables import MeteocatVariables
|
|
6
6
|
from .const import BASE_URL, STATION_DATA_URL
|
|
7
7
|
from .exceptions import (
|
|
@@ -41,6 +41,17 @@ class MeteocatStationData:
|
|
|
41
41
|
"""
|
|
42
42
|
now = datetime.now()
|
|
43
43
|
return now.year, now.month, now.day
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def get_previous_date():
|
|
47
|
+
"""
|
|
48
|
+
Obtiene la fecha del día anterior en formato numérico.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
tuple: Año (YYYY), mes (MM), día (DD) como enteros.
|
|
52
|
+
"""
|
|
53
|
+
yesterday = datetime.now() - timedelta(days=1)
|
|
54
|
+
return yesterday.year, yesterday.month, yesterday.day
|
|
44
55
|
|
|
45
56
|
async def get_station_data(self, station_id: str):
|
|
46
57
|
"""
|
|
@@ -66,7 +77,7 @@ class MeteocatStationData:
|
|
|
66
77
|
# Gestionar errores según el código de estado
|
|
67
78
|
if response.status == 400:
|
|
68
79
|
error_data = await response.json()
|
|
69
|
-
#
|
|
80
|
+
# Filtrar si el mensaje contiene una fecha válida
|
|
70
81
|
if "message" in error_data:
|
|
71
82
|
match = re.search(r'entre (\d{2}-\d{2}-\d{4}) i', error_data["message"])
|
|
72
83
|
if match:
|
|
@@ -82,6 +93,20 @@ class MeteocatStationData:
|
|
|
82
93
|
raise UnknownAPIError(
|
|
83
94
|
f"Failed with the valid date {last_valid_date}: {await new_response.text()}"
|
|
84
95
|
)
|
|
96
|
+
|
|
97
|
+
# Filtrar si el mensaje es "L'estació '<código>' no mesura la variable 'null'"
|
|
98
|
+
if re.search(r"L'estaci\u00f3 '.*?' no mesura la variable 'null'", error_data.get("message", "")):
|
|
99
|
+
any, mes, dia = self.get_previous_date() # Obtener la fecha del día anterior
|
|
100
|
+
new_url = f"{BASE_URL}{STATION_DATA_URL}".format(
|
|
101
|
+
codiEstacio=station_id, any=any, mes=f"{mes:02d}", dia=f"{dia:02d}"
|
|
102
|
+
)
|
|
103
|
+
async with session.get(new_url, headers=self.headers) as new_response:
|
|
104
|
+
if new_response.status == 200:
|
|
105
|
+
return await new_response.json()
|
|
106
|
+
raise UnknownAPIError(
|
|
107
|
+
f"Failed with the previous date: {await new_response.text()}"
|
|
108
|
+
)
|
|
109
|
+
|
|
85
110
|
raise BadRequestError(await response.json())
|
|
86
111
|
elif response.status == 403:
|
|
87
112
|
error_data = await response.json()
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import aiohttp
|
|
2
|
+
from .const import BASE_URL, INFO_STATION_URL
|
|
3
|
+
from .exceptions import BadRequestError, ForbiddenError, TooManyRequestsError, InternalServerError, UnknownAPIError
|
|
4
|
+
|
|
5
|
+
class MeteocatInfoStation:
|
|
6
|
+
"""Clase para interactuar con la lista de municipios de la API de Meteocat."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, api_key: str):
|
|
9
|
+
"""
|
|
10
|
+
Inicializa la clase MeteocatTown.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
api_key (str): Clave de API para autenticar las solicitudes.
|
|
14
|
+
"""
|
|
15
|
+
self.api_key = api_key
|
|
16
|
+
self.headers = {
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
"X-Api-Key": self.api_key,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async def get_infostation(self, station_id: str):
|
|
22
|
+
"""
|
|
23
|
+
Obtiene los metadatos de la estación desde la API de Meteocat.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
dict: Datos de la estación. Nombre, coordenadas, altitud, provincia, comarca, etc.
|
|
27
|
+
"""
|
|
28
|
+
url = f"{BASE_URL}{INFO_STATION_URL}".format(
|
|
29
|
+
codi_estacio=station_id
|
|
30
|
+
)
|
|
31
|
+
async with aiohttp.ClientSession() as session:
|
|
32
|
+
try:
|
|
33
|
+
async with session.get(url, headers=self.headers) as response:
|
|
34
|
+
if response.status == 200:
|
|
35
|
+
return await response.json()
|
|
36
|
+
|
|
37
|
+
# Gestionar errores según el código de estado
|
|
38
|
+
if response.status == 400:
|
|
39
|
+
raise BadRequestError(await response.json())
|
|
40
|
+
elif response.status == 403:
|
|
41
|
+
error_data = await response.json()
|
|
42
|
+
if error_data.get("message") == "Forbidden":
|
|
43
|
+
raise ForbiddenError(error_data)
|
|
44
|
+
elif error_data.get("message") == "Missing Authentication Token":
|
|
45
|
+
raise ForbiddenError(error_data)
|
|
46
|
+
elif response.status == 429:
|
|
47
|
+
raise TooManyRequestsError(await response.json())
|
|
48
|
+
elif response.status == 500:
|
|
49
|
+
raise InternalServerError(await response.json())
|
|
50
|
+
else:
|
|
51
|
+
raise UnknownAPIError(f"Unexpected error {response.status}: {await response.text()}")
|
|
52
|
+
|
|
53
|
+
except aiohttp.ClientError as e:
|
|
54
|
+
raise UnknownAPIError(
|
|
55
|
+
message=f"Error al conectar con la API de Meteocat: {str(e)}",
|
|
56
|
+
status_code=0,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
except Exception as ex:
|
|
60
|
+
raise UnknownAPIError(
|
|
61
|
+
message=f"Error inesperado: {str(ex)}",
|
|
62
|
+
status_code=0,
|
|
63
|
+
)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import aiohttp
|
|
2
|
+
from .const import BASE_URL, QUOTES_URL
|
|
3
|
+
from .exceptions import (
|
|
4
|
+
BadRequestError,
|
|
5
|
+
ForbiddenError,
|
|
6
|
+
TooManyRequestsError,
|
|
7
|
+
InternalServerError,
|
|
8
|
+
UnknownAPIError
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
class MeteocatQuotes:
|
|
12
|
+
"""
|
|
13
|
+
Clase para interactuar con la API de Meteocat y obtener las cuotas de peticiones realizadas."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, api_key: str):
|
|
16
|
+
"""
|
|
17
|
+
Inicializa la clase MeteocatStations.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
api_key (str): Clave de API para autenticar las solicitudes.
|
|
21
|
+
"""
|
|
22
|
+
self.api_key = api_key
|
|
23
|
+
self.headers = {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
"X-Api-Key": self.api_key,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async def get_quotes(self):
|
|
29
|
+
"""
|
|
30
|
+
Obtiene la lista de cuotas.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
dict: Lista de cuotas.
|
|
34
|
+
"""
|
|
35
|
+
url = f"{BASE_URL}{QUOTES_URL}"
|
|
36
|
+
async with aiohttp.ClientSession() as session:
|
|
37
|
+
try:
|
|
38
|
+
async with session.get(url, headers=self.headers) as response:
|
|
39
|
+
if response.status == 200:
|
|
40
|
+
return await response.json()
|
|
41
|
+
|
|
42
|
+
# Gestionar errores según el código de estado
|
|
43
|
+
if response.status == 400:
|
|
44
|
+
raise BadRequestError(await response.json())
|
|
45
|
+
elif response.status == 403:
|
|
46
|
+
error_data = await response.json()
|
|
47
|
+
if error_data.get("message") == "Forbidden":
|
|
48
|
+
raise ForbiddenError(error_data)
|
|
49
|
+
elif error_data.get("message") == "Missing Authentication Token":
|
|
50
|
+
raise ForbiddenError(error_data)
|
|
51
|
+
elif response.status == 429:
|
|
52
|
+
raise TooManyRequestsError(await response.json())
|
|
53
|
+
elif response.status == 500:
|
|
54
|
+
raise InternalServerError(await response.json())
|
|
55
|
+
else:
|
|
56
|
+
raise UnknownAPIError(
|
|
57
|
+
f"Unexpected error {response.status}: {await response.text()}"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
except aiohttp.ClientError as e:
|
|
61
|
+
raise UnknownAPIError(
|
|
62
|
+
message=f"Error al conectar con la API de Meteocat: {str(e)}",
|
|
63
|
+
status_code=0,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
except Exception as ex:
|
|
67
|
+
raise UnknownAPIError(
|
|
68
|
+
message=f"Error inesperado: {str(ex)}",
|
|
69
|
+
status_code=0,
|
|
70
|
+
)
|
|
71
|
+
|
package/meteocatpy/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# version.py
|
|
2
|
-
__version__ = "0.0.
|
|
2
|
+
__version__ = "0.0.19"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "meteocatpy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "[](https://opensource.org/licenses/Apache-2.0)\r [](https://pypi.org/project/meteocatpy)\r [](https://gitlab.com/figorr/meteocatpy/commits/master)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
package/pyproject.toml
CHANGED
package/setup.cfg
CHANGED
|
@@ -14,6 +14,7 @@ show_missing = true
|
|
|
14
14
|
testpaths = tests
|
|
15
15
|
norecursedirs = .git
|
|
16
16
|
asyncio_mode = auto
|
|
17
|
+
asyncio_default_fixture_loop_scope = function
|
|
17
18
|
addopts =
|
|
18
19
|
-p syrupy
|
|
19
20
|
--strict
|
|
@@ -55,7 +56,7 @@ forced_separate = tests
|
|
|
55
56
|
combine_as_imports = true
|
|
56
57
|
|
|
57
58
|
[mypy]
|
|
58
|
-
python_version = 3.
|
|
59
|
+
python_version = 3.12
|
|
59
60
|
ignore_errors = true
|
|
60
61
|
follow_imports = silent
|
|
61
62
|
ignore_missing_imports = true
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pytest
|
|
3
|
+
import json
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
from meteocatpy.alerts import MeteocatAlerts
|
|
6
|
+
|
|
7
|
+
# Cargar variables desde el archivo .env
|
|
8
|
+
load_dotenv()
|
|
9
|
+
|
|
10
|
+
# Obtener los valores del archivo .env
|
|
11
|
+
API_KEY = os.getenv("METEOCAT_API_KEY")
|
|
12
|
+
|
|
13
|
+
# Asegúrate de que las variables estén definidas
|
|
14
|
+
assert API_KEY, "API Key is required"
|
|
15
|
+
|
|
16
|
+
@pytest.mark.asyncio
|
|
17
|
+
async def test_alerts():
|
|
18
|
+
# Crear una instancia de MeteocatAlerts con la API Key
|
|
19
|
+
alerts_client = MeteocatAlerts(API_KEY)
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
# Obtener los datos de las alertas
|
|
23
|
+
alerts_data = await alerts_client.get_alerts()
|
|
24
|
+
except Exception as e:
|
|
25
|
+
pytest.fail(f"Failed to fetch alerts: {e}")
|
|
26
|
+
|
|
27
|
+
# Crear la carpeta si no existe
|
|
28
|
+
os.makedirs('tests/files', exist_ok=True)
|
|
29
|
+
|
|
30
|
+
# Guardar los datos de las alertas en un archivo JSON
|
|
31
|
+
with open('tests/files/alerts.json', 'w', encoding='utf-8') as f:
|
|
32
|
+
json.dump(alerts_data, f, ensure_ascii=False, indent=4)
|
|
33
|
+
|
|
34
|
+
# Validar la respuesta
|
|
35
|
+
assert isinstance(alerts_data, list), "Alerts data should be a list"
|
|
36
|
+
if not alerts_data:
|
|
37
|
+
# Mensaje indicando que no hay alertas activas
|
|
38
|
+
print("No active alerts.")
|
|
39
|
+
assert alerts_data == [], "No active alerts."
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pytest
|
|
3
|
+
import json
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
from meteocatpy.infostation import MeteocatInfoStation
|
|
6
|
+
|
|
7
|
+
# Cargar variables desde el archivo .env
|
|
8
|
+
load_dotenv()
|
|
9
|
+
|
|
10
|
+
# Obtener los valores del archivo .env
|
|
11
|
+
API_KEY = os.getenv("METEOCAT_API_KEY")
|
|
12
|
+
STATION_CODI_TEST = os.getenv("STATION_CODI_TEST")
|
|
13
|
+
|
|
14
|
+
# Asegúrate de que las variables estén definidas
|
|
15
|
+
assert API_KEY, "API Key is required"
|
|
16
|
+
assert STATION_CODI_TEST, "Station codi test is required"
|
|
17
|
+
|
|
18
|
+
@pytest.mark.asyncio
|
|
19
|
+
async def test_infostation():
|
|
20
|
+
# Crear una instancia de MeteocatInfoStation con la API Key
|
|
21
|
+
infostation_client = MeteocatInfoStation(API_KEY)
|
|
22
|
+
|
|
23
|
+
# Obtener los datos de la estación
|
|
24
|
+
station_data = await infostation_client.get_infostation(STATION_CODI_TEST)
|
|
25
|
+
|
|
26
|
+
# Crear la carpeta si no existe
|
|
27
|
+
os.makedirs('tests/files', exist_ok=True)
|
|
28
|
+
|
|
29
|
+
# Guardar los datos de las estaciones en un archivo JSON
|
|
30
|
+
with open(f'tests/files/station_{STATION_CODI_TEST}_info.json', 'w', encoding='utf-8') as f:
|
|
31
|
+
json.dump(station_data, f, ensure_ascii=False, indent=4)
|
|
32
|
+
|
|
33
|
+
# Verificar que los datos no estén vacíos
|
|
34
|
+
assert station_data, "Estaciones info is empty"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pytest
|
|
3
|
+
import json
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
from meteocatpy.quotes import MeteocatQuotes
|
|
6
|
+
|
|
7
|
+
# Cargar variables desde el archivo .env
|
|
8
|
+
load_dotenv()
|
|
9
|
+
|
|
10
|
+
# Obtener los valores del archivo .env
|
|
11
|
+
API_KEY = os.getenv("METEOCAT_API_KEY")
|
|
12
|
+
|
|
13
|
+
# Asegúrate de que las variables estén definidas
|
|
14
|
+
assert API_KEY, "API Key is required"
|
|
15
|
+
|
|
16
|
+
@pytest.mark.asyncio
|
|
17
|
+
async def test_quotes():
|
|
18
|
+
# Crear una instancia de MeteocatQuotes con la API Key
|
|
19
|
+
quotes_client = MeteocatQuotes(API_KEY)
|
|
20
|
+
|
|
21
|
+
# Obtener las cuotas
|
|
22
|
+
quotes_data = await quotes_client.get_quotes()
|
|
23
|
+
|
|
24
|
+
# Crear la carpeta si no existe
|
|
25
|
+
os.makedirs('tests/files', exist_ok=True)
|
|
26
|
+
|
|
27
|
+
# Guardar los datos de las cuotas en un archivo JSON
|
|
28
|
+
with open('tests/files/quotes.json', 'w', encoding='utf-8') as f:
|
|
29
|
+
json.dump(quotes_data, f, ensure_ascii=False, indent=4)
|
|
30
|
+
|
|
31
|
+
# Verificar que las cuotas no estén vacías
|
|
32
|
+
assert quotes_data, "Quotes data is empty"
|