meteocatpy 0.0.11 → 0.0.13
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/.github/workflows/release.yml +33 -33
- package/.gitlab-ci.yml +46 -46
- package/.pre-commit-config.yaml +37 -37
- package/.releaserc +23 -23
- package/.releaserc.toml +14 -14
- package/AUTHORS.md +12 -12
- package/CHANGELOG.md +187 -171
- package/README.md +61 -61
- package/filetree.py +48 -48
- package/filetree.txt +48 -48
- package/meteocatpy/README.md +61 -61
- package/meteocatpy/__init__.py +27 -27
- package/meteocatpy/const.py +10 -10
- package/meteocatpy/data.py +93 -93
- package/meteocatpy/exceptions.py +35 -35
- package/meteocatpy/forecast.py +137 -137
- package/meteocatpy/helpers.py +46 -46
- package/meteocatpy/stations.py +71 -71
- package/meteocatpy/symbols.py +89 -89
- package/meteocatpy/town.py +61 -61
- package/meteocatpy/townstations.py +99 -99
- package/meteocatpy/variables.py +77 -77
- package/meteocatpy/version.py +2 -2
- package/package.json +23 -23
- package/poetry.lock +3313 -3313
- package/pyproject.toml +72 -72
- package/releaserc.json +17 -17
- package/requirements.test.txt +3 -3
- package/setup.cfg +64 -64
- package/setup.py +10 -10
- package/tests/data_test.py +122 -122
- package/tests/import_test.py +18 -18
- package/tests/integration_test_complete.py +76 -76
- package/tests/integration_test_forecast.py +54 -54
- package/tests/integration_test_station_data.py +33 -33
- package/tests/integration_test_stations.py +31 -31
- package/tests/integration_test_symbols.py +68 -68
- package/tests/integration_test_town.py +32 -32
- package/tests/integration_test_town_stations.py +36 -36
- package/tests/integration_test_variables.py +32 -32
package/filetree.txt
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
└── .github/
|
|
2
|
-
└── workflows/
|
|
3
|
-
├── release.yml
|
|
4
|
-
├── .gitignore
|
|
5
|
-
├── .gitlab-ci.yml
|
|
6
|
-
├── .pre-commit-config.yaml
|
|
7
|
-
├── .releaserc
|
|
8
|
-
├── .releaserc.toml
|
|
9
|
-
├── AUTHORS.md
|
|
10
|
-
├── CHANGELOG.md
|
|
11
|
-
├── LICENSE
|
|
12
|
-
├── README.md
|
|
13
|
-
├── filetree.py
|
|
14
|
-
├── filetree.txt
|
|
15
|
-
└── meteocatpy/
|
|
16
|
-
├── README.md
|
|
17
|
-
├── __init__.py
|
|
18
|
-
├── const.py
|
|
19
|
-
├── data.py
|
|
20
|
-
├── exceptions.py
|
|
21
|
-
├── forecast.py
|
|
22
|
-
├── helpers.py
|
|
23
|
-
├── py.typed
|
|
24
|
-
├── stations.py
|
|
25
|
-
├── symbols.py
|
|
26
|
-
├── town.py
|
|
27
|
-
├── townstations.py
|
|
28
|
-
├── variables.py
|
|
29
|
-
├── version.py
|
|
30
|
-
├── package-lock.json
|
|
31
|
-
├── package.json
|
|
32
|
-
├── poetry.lock
|
|
33
|
-
├── pyproject.toml
|
|
34
|
-
├── releaserc.json
|
|
35
|
-
├── requirements.test.txt
|
|
36
|
-
├── setup.cfg
|
|
37
|
-
├── setup.py
|
|
38
|
-
└── tests/
|
|
39
|
-
├── data_test.py
|
|
40
|
-
├── import_test.py
|
|
41
|
-
├── integration_test_complete.py
|
|
42
|
-
├── integration_test_forecast.py
|
|
43
|
-
├── integration_test_station_data.py
|
|
44
|
-
├── integration_test_stations.py
|
|
45
|
-
├── integration_test_symbols.py
|
|
46
|
-
├── integration_test_town.py
|
|
47
|
-
├── integration_test_town_stations.py
|
|
48
|
-
├── integration_test_variables.py
|
|
1
|
+
└── .github/
|
|
2
|
+
└── workflows/
|
|
3
|
+
├── release.yml
|
|
4
|
+
├── .gitignore
|
|
5
|
+
├── .gitlab-ci.yml
|
|
6
|
+
├── .pre-commit-config.yaml
|
|
7
|
+
├── .releaserc
|
|
8
|
+
├── .releaserc.toml
|
|
9
|
+
├── AUTHORS.md
|
|
10
|
+
├── CHANGELOG.md
|
|
11
|
+
├── LICENSE
|
|
12
|
+
├── README.md
|
|
13
|
+
├── filetree.py
|
|
14
|
+
├── filetree.txt
|
|
15
|
+
└── meteocatpy/
|
|
16
|
+
├── README.md
|
|
17
|
+
├── __init__.py
|
|
18
|
+
├── const.py
|
|
19
|
+
├── data.py
|
|
20
|
+
├── exceptions.py
|
|
21
|
+
├── forecast.py
|
|
22
|
+
├── helpers.py
|
|
23
|
+
├── py.typed
|
|
24
|
+
├── stations.py
|
|
25
|
+
├── symbols.py
|
|
26
|
+
├── town.py
|
|
27
|
+
├── townstations.py
|
|
28
|
+
├── variables.py
|
|
29
|
+
├── version.py
|
|
30
|
+
├── package-lock.json
|
|
31
|
+
├── package.json
|
|
32
|
+
├── poetry.lock
|
|
33
|
+
├── pyproject.toml
|
|
34
|
+
├── releaserc.json
|
|
35
|
+
├── requirements.test.txt
|
|
36
|
+
├── setup.cfg
|
|
37
|
+
├── setup.py
|
|
38
|
+
└── tests/
|
|
39
|
+
├── data_test.py
|
|
40
|
+
├── import_test.py
|
|
41
|
+
├── integration_test_complete.py
|
|
42
|
+
├── integration_test_forecast.py
|
|
43
|
+
├── integration_test_station_data.py
|
|
44
|
+
├── integration_test_stations.py
|
|
45
|
+
├── integration_test_symbols.py
|
|
46
|
+
├── integration_test_town.py
|
|
47
|
+
├── integration_test_town_stations.py
|
|
48
|
+
├── integration_test_variables.py
|
package/meteocatpy/README.md
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
# Meteocat Python Package for Meteocat Home Assistant Integration
|
|
2
|
-
|
|
3
|
-
[](https://opensource.org/licenses/Apache-2.0)
|
|
4
|
-
[](https://pypi.org/project/meteocatpy)
|
|
5
|
-
[](https://gitlab.com/figorr/meteocatpy/commits/master)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
`meteocatpy` is a Python package to interact with the Meteocat API. Allows you to obtain meteorological data and lists of municipalities from the Meteocat API.
|
|
9
|
-
|
|
10
|
-
**NOTE:** Meteocat API requires to use an API_KEY, you should ask to (https://apidocs.meteocat.gencat.cat/documentacio/acces-ciutada-i-administracio/)
|
|
11
|
-
|
|
12
|
-
# Installation
|
|
13
|
-
|
|
14
|
-
You can install the package from PyPI using `pip`:
|
|
15
|
-
```bash
|
|
16
|
-
pip install meteocatpy
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
from meteocatpy.town import MeteocatTown
|
|
21
|
-
|
|
22
|
-
# Replace 'tu_api_key' with your actual API key
|
|
23
|
-
API_KEY = "tu_api_key"
|
|
24
|
-
town_client = MeteocatTown(API_KEY)
|
|
25
|
-
|
|
26
|
-
# Get a list of municipalities (asynchronous call)
|
|
27
|
-
municipios_data = await town_client.get_municipis()
|
|
28
|
-
print(municipis)
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
# Credits
|
|
32
|
-
|
|
33
|
-
This is a personal project.
|
|
34
|
-
|
|
35
|
-
Authors:
|
|
36
|
-
- Figorr
|
|
37
|
-
|
|
38
|
-
# Contributing
|
|
39
|
-
|
|
40
|
-
If you would like to contribute to this project, please open an issue or create a pull request. I'd be happy to review your contributions!
|
|
41
|
-
|
|
42
|
-
1. [Check for open features/bugs](https://gitlab.com/figorr/meteocatpy/issues)
|
|
43
|
-
or [initiate a discussion on one](https://gitlab.com/figorr/meteocatpy/issues/new).
|
|
44
|
-
2. [Fork the repository](https://gitlab.com/figorr/meteocatpy/forks/new).
|
|
45
|
-
3. Install the dev environment: `make init`.
|
|
46
|
-
4. Enter the virtual environment: `pipenv shell`
|
|
47
|
-
5. Code your new feature or bug fix.
|
|
48
|
-
6. Write a test that covers your new functionality.
|
|
49
|
-
7. Update `README.md` with any new documentation.
|
|
50
|
-
8. Run tests and ensure 100% code coverage for your contribution: `make coverage`
|
|
51
|
-
9. Ensure you have no linting errors: `make lint`
|
|
52
|
-
10. Ensure you have typed your code correctly: `make typing`
|
|
53
|
-
11. Add yourself to `AUTHORS.md`.
|
|
54
|
-
12. Submit a pull request!
|
|
55
|
-
|
|
56
|
-
# License
|
|
57
|
-
|
|
58
|
-
[Apache-2.0](LICENSE). By providing a contribution, you agree the contribution is licensed under Apache-2.0.
|
|
59
|
-
|
|
60
|
-
# API Reference
|
|
61
|
-
|
|
1
|
+
# Meteocat Python Package for Meteocat Home Assistant Integration
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
4
|
+
[](https://pypi.org/project/meteocatpy)
|
|
5
|
+
[](https://gitlab.com/figorr/meteocatpy/commits/master)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
`meteocatpy` is a Python package to interact with the Meteocat API. Allows you to obtain meteorological data and lists of municipalities from the Meteocat API.
|
|
9
|
+
|
|
10
|
+
**NOTE:** Meteocat API requires to use an API_KEY, you should ask to (https://apidocs.meteocat.gencat.cat/documentacio/acces-ciutada-i-administracio/)
|
|
11
|
+
|
|
12
|
+
# Installation
|
|
13
|
+
|
|
14
|
+
You can install the package from PyPI using `pip`:
|
|
15
|
+
```bash
|
|
16
|
+
pip install meteocatpy
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
from meteocatpy.town import MeteocatTown
|
|
21
|
+
|
|
22
|
+
# Replace 'tu_api_key' with your actual API key
|
|
23
|
+
API_KEY = "tu_api_key"
|
|
24
|
+
town_client = MeteocatTown(API_KEY)
|
|
25
|
+
|
|
26
|
+
# Get a list of municipalities (asynchronous call)
|
|
27
|
+
municipios_data = await town_client.get_municipis()
|
|
28
|
+
print(municipis)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
# Credits
|
|
32
|
+
|
|
33
|
+
This is a personal project.
|
|
34
|
+
|
|
35
|
+
Authors:
|
|
36
|
+
- Figorr
|
|
37
|
+
|
|
38
|
+
# Contributing
|
|
39
|
+
|
|
40
|
+
If you would like to contribute to this project, please open an issue or create a pull request. I'd be happy to review your contributions!
|
|
41
|
+
|
|
42
|
+
1. [Check for open features/bugs](https://gitlab.com/figorr/meteocatpy/issues)
|
|
43
|
+
or [initiate a discussion on one](https://gitlab.com/figorr/meteocatpy/issues/new).
|
|
44
|
+
2. [Fork the repository](https://gitlab.com/figorr/meteocatpy/forks/new).
|
|
45
|
+
3. Install the dev environment: `make init`.
|
|
46
|
+
4. Enter the virtual environment: `pipenv shell`
|
|
47
|
+
5. Code your new feature or bug fix.
|
|
48
|
+
6. Write a test that covers your new functionality.
|
|
49
|
+
7. Update `README.md` with any new documentation.
|
|
50
|
+
8. Run tests and ensure 100% code coverage for your contribution: `make coverage`
|
|
51
|
+
9. Ensure you have no linting errors: `make lint`
|
|
52
|
+
10. Ensure you have typed your code correctly: `make typing`
|
|
53
|
+
11. Add yourself to `AUTHORS.md`.
|
|
54
|
+
12. Submit a pull request!
|
|
55
|
+
|
|
56
|
+
# License
|
|
57
|
+
|
|
58
|
+
[Apache-2.0](LICENSE). By providing a contribution, you agree the contribution is licensed under Apache-2.0.
|
|
59
|
+
|
|
60
|
+
# API Reference
|
|
61
|
+
|
|
62
62
|
[See the docs 📚](https://apidocs.meteocat.gencat.cat/section/informacio-general/).
|
package/meteocatpy/__init__.py
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
"""METEOCAT API.
|
|
2
|
-
|
|
3
|
-
Python Package to collect data from Meteocat API and interact with Meteocat Home Assistant Integration
|
|
4
|
-
SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
|
|
6
|
-
For more details about this API, please refer to the documentation at
|
|
7
|
-
https://gitlab.com/figorr/meteocatpy
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
# meteocatpy/__init__.py
|
|
11
|
-
from .town import MeteocatTown
|
|
12
|
-
from .forecast import MeteocatForecast
|
|
13
|
-
from .symbols import MeteocatSymbols
|
|
14
|
-
from .stations import MeteocatStations
|
|
15
|
-
from .townstations import MeteocatTownStations
|
|
16
|
-
from .data import MeteocatStationData
|
|
17
|
-
from .variables import MeteocatVariables
|
|
18
|
-
|
|
19
|
-
__all__ = [
|
|
20
|
-
"MeteocatTown",
|
|
21
|
-
"MeteocatForecast",
|
|
22
|
-
"MeteocatSymbols",
|
|
23
|
-
"MeteocatStations",
|
|
24
|
-
"MeteocatTownStations",
|
|
25
|
-
"MeteocatStationData",
|
|
26
|
-
"MeteocatVariables"
|
|
27
|
-
]
|
|
1
|
+
"""METEOCAT API.
|
|
2
|
+
|
|
3
|
+
Python Package to collect data from Meteocat API and interact with Meteocat Home Assistant Integration
|
|
4
|
+
SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
|
|
6
|
+
For more details about this API, please refer to the documentation at
|
|
7
|
+
https://gitlab.com/figorr/meteocatpy
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# meteocatpy/__init__.py
|
|
11
|
+
from .town import MeteocatTown
|
|
12
|
+
from .forecast import MeteocatForecast
|
|
13
|
+
from .symbols import MeteocatSymbols
|
|
14
|
+
from .stations import MeteocatStations
|
|
15
|
+
from .townstations import MeteocatTownStations
|
|
16
|
+
from .data import MeteocatStationData
|
|
17
|
+
from .variables import MeteocatVariables
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"MeteocatTown",
|
|
21
|
+
"MeteocatForecast",
|
|
22
|
+
"MeteocatSymbols",
|
|
23
|
+
"MeteocatStations",
|
|
24
|
+
"MeteocatTownStations",
|
|
25
|
+
"MeteocatStationData",
|
|
26
|
+
"MeteocatVariables"
|
|
27
|
+
]
|
package/meteocatpy/const.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"""meteocatpy constants."""
|
|
2
|
-
BASE_URL = "https://api.meteo.cat"
|
|
3
|
-
MUNICIPIS_LIST_URL = "/referencia/v1/municipis"
|
|
4
|
-
MUNICIPIS_HORA_URL = "/pronostic/v1/municipalHoraria/{codi}"
|
|
5
|
-
MUNICIPIS_DIA_URL = "/pronostic/v1/municipal/{codi}"
|
|
6
|
-
SYMBOLS_URL = "/referencia/v1/simbols"
|
|
7
|
-
STATIONS_LIST_URL = "/xema/v1/estacions/metadades"
|
|
8
|
-
STATIONS_MUNICIPI_URL = "/xema/v1/representatives/metadades/municipis/{codi_municipi}/variables/{codi_variable}"
|
|
9
|
-
VARIABLES_URL = "/xema/v1/variables/mesurades/metadades"
|
|
10
|
-
STATION_DATA_URL = "/xema/v1/estacions/mesurades/{codiEstacio}/{any}/{mes}/{dia}"
|
|
1
|
+
"""meteocatpy constants."""
|
|
2
|
+
BASE_URL = "https://api.meteo.cat"
|
|
3
|
+
MUNICIPIS_LIST_URL = "/referencia/v1/municipis"
|
|
4
|
+
MUNICIPIS_HORA_URL = "/pronostic/v1/municipalHoraria/{codi}"
|
|
5
|
+
MUNICIPIS_DIA_URL = "/pronostic/v1/municipal/{codi}"
|
|
6
|
+
SYMBOLS_URL = "/referencia/v1/simbols"
|
|
7
|
+
STATIONS_LIST_URL = "/xema/v1/estacions/metadades"
|
|
8
|
+
STATIONS_MUNICIPI_URL = "/xema/v1/representatives/metadades/municipis/{codi_municipi}/variables/{codi_variable}"
|
|
9
|
+
VARIABLES_URL = "/xema/v1/variables/mesurades/metadades"
|
|
10
|
+
STATION_DATA_URL = "/xema/v1/estacions/mesurades/{codiEstacio}/{any}/{mes}/{dia}"
|
package/meteocatpy/data.py
CHANGED
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import aiohttp
|
|
2
|
-
import logging
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
from .variables import MeteocatVariables
|
|
5
|
-
from .const import BASE_URL, STATION_DATA_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 MeteocatStationData:
|
|
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 MeteocatStationData.
|
|
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
|
-
self.variables = MeteocatVariables(api_key)
|
|
32
|
-
|
|
33
|
-
@staticmethod
|
|
34
|
-
def get_current_date():
|
|
35
|
-
"""
|
|
36
|
-
Obtiene la fecha actual en formato numérico.
|
|
37
|
-
|
|
38
|
-
Returns:
|
|
39
|
-
tuple: Año (YYYY), mes (MM), día (DD) como enteros.
|
|
40
|
-
"""
|
|
41
|
-
now = datetime.now()
|
|
42
|
-
return now.year, now.month, now.day
|
|
43
|
-
|
|
44
|
-
async def get_station_data(self, station_id: str):
|
|
45
|
-
"""
|
|
46
|
-
Obtiene los datos meteorológicos de una estación desde la API de Meteocat.
|
|
47
|
-
|
|
48
|
-
Args:
|
|
49
|
-
station_id (str): Código de la estación.
|
|
50
|
-
|
|
51
|
-
Returns:
|
|
52
|
-
dict: Datos meteorológicos de la estación.
|
|
53
|
-
"""
|
|
54
|
-
any, mes, dia = self.get_current_date() # Calcula la fecha actual
|
|
55
|
-
url = f"{BASE_URL}{STATION_DATA_URL}".format(
|
|
56
|
-
codiEstacio=station_id, any=any, mes=f"{mes:02d}", dia=f"{dia:02d}"
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
async with aiohttp.ClientSession() as session:
|
|
60
|
-
try:
|
|
61
|
-
async with session.get(url, headers=self.headers) as response:
|
|
62
|
-
if response.status == 200:
|
|
63
|
-
return await response.json()
|
|
64
|
-
|
|
65
|
-
# Gestionar errores según el código de estado
|
|
66
|
-
if response.status == 400:
|
|
67
|
-
raise BadRequestError(await response.json())
|
|
68
|
-
elif response.status == 403:
|
|
69
|
-
error_data = await response.json()
|
|
70
|
-
if error_data.get("message") == "Forbidden":
|
|
71
|
-
raise ForbiddenError(error_data)
|
|
72
|
-
elif error_data.get("message") == "Missing Authentication Token":
|
|
73
|
-
raise ForbiddenError(error_data)
|
|
74
|
-
elif response.status == 429:
|
|
75
|
-
raise TooManyRequestsError(await response.json())
|
|
76
|
-
elif response.status == 500:
|
|
77
|
-
raise InternalServerError(await response.json())
|
|
78
|
-
else:
|
|
79
|
-
raise UnknownAPIError(
|
|
80
|
-
f"Unexpected error {response.status}: {await response.text()}"
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
except aiohttp.ClientError as e:
|
|
84
|
-
raise UnknownAPIError(
|
|
85
|
-
message=f"Error al conectar con la API de Meteocat: {str(e)}",
|
|
86
|
-
status_code=0,
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
except Exception as ex:
|
|
90
|
-
raise UnknownAPIError(
|
|
91
|
-
message=f"Error inesperado: {str(ex)}",
|
|
92
|
-
status_code=0,
|
|
93
|
-
)
|
|
1
|
+
import aiohttp
|
|
2
|
+
import logging
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from .variables import MeteocatVariables
|
|
5
|
+
from .const import BASE_URL, STATION_DATA_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 MeteocatStationData:
|
|
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 MeteocatStationData.
|
|
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
|
+
self.variables = MeteocatVariables(api_key)
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def get_current_date():
|
|
35
|
+
"""
|
|
36
|
+
Obtiene la fecha actual en formato numérico.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
tuple: Año (YYYY), mes (MM), día (DD) como enteros.
|
|
40
|
+
"""
|
|
41
|
+
now = datetime.now()
|
|
42
|
+
return now.year, now.month, now.day
|
|
43
|
+
|
|
44
|
+
async def get_station_data(self, station_id: str):
|
|
45
|
+
"""
|
|
46
|
+
Obtiene los datos meteorológicos de una estación desde la API de Meteocat.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
station_id (str): Código de la estación.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
dict: Datos meteorológicos de la estación.
|
|
53
|
+
"""
|
|
54
|
+
any, mes, dia = self.get_current_date() # Calcula la fecha actual
|
|
55
|
+
url = f"{BASE_URL}{STATION_DATA_URL}".format(
|
|
56
|
+
codiEstacio=station_id, any=any, mes=f"{mes:02d}", dia=f"{dia:02d}"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
async with aiohttp.ClientSession() as session:
|
|
60
|
+
try:
|
|
61
|
+
async with session.get(url, headers=self.headers) as response:
|
|
62
|
+
if response.status == 200:
|
|
63
|
+
return await response.json()
|
|
64
|
+
|
|
65
|
+
# Gestionar errores según el código de estado
|
|
66
|
+
if response.status == 400:
|
|
67
|
+
raise BadRequestError(await response.json())
|
|
68
|
+
elif response.status == 403:
|
|
69
|
+
error_data = await response.json()
|
|
70
|
+
if error_data.get("message") == "Forbidden":
|
|
71
|
+
raise ForbiddenError(error_data)
|
|
72
|
+
elif error_data.get("message") == "Missing Authentication Token":
|
|
73
|
+
raise ForbiddenError(error_data)
|
|
74
|
+
elif response.status == 429:
|
|
75
|
+
raise TooManyRequestsError(await response.json())
|
|
76
|
+
elif response.status == 500:
|
|
77
|
+
raise InternalServerError(await response.json())
|
|
78
|
+
else:
|
|
79
|
+
raise UnknownAPIError(
|
|
80
|
+
f"Unexpected error {response.status}: {await response.text()}"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
except aiohttp.ClientError as e:
|
|
84
|
+
raise UnknownAPIError(
|
|
85
|
+
message=f"Error al conectar con la API de Meteocat: {str(e)}",
|
|
86
|
+
status_code=0,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
except Exception as ex:
|
|
90
|
+
raise UnknownAPIError(
|
|
91
|
+
message=f"Error inesperado: {str(ex)}",
|
|
92
|
+
status_code=0,
|
|
93
|
+
)
|
package/meteocatpy/exceptions.py
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
"""METEOCAT API exceptions."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
class MeteocatAPIError(Exception):
|
|
6
|
-
"""Clase base para todos los errores de la API de Meteocat."""
|
|
7
|
-
def __init__(self, message: str, status_code: int, aws_info: dict = None):
|
|
8
|
-
super().__init__(message)
|
|
9
|
-
self.status_code = status_code
|
|
10
|
-
self.aws_info = aws_info
|
|
11
|
-
|
|
12
|
-
class BadRequestError(MeteocatAPIError):
|
|
13
|
-
"""Error 400: Bad request."""
|
|
14
|
-
def __init__(self, message: str, aws_info: dict = None):
|
|
15
|
-
super().__init__(message, 400, aws_info)
|
|
16
|
-
|
|
17
|
-
class ForbiddenError(MeteocatAPIError):
|
|
18
|
-
"""Error 403: Forbidden."""
|
|
19
|
-
def __init__(self, message: str, aws_info: dict = None):
|
|
20
|
-
super().__init__(message, 403, aws_info)
|
|
21
|
-
|
|
22
|
-
class TooManyRequestsError(MeteocatAPIError):
|
|
23
|
-
"""Error 429: Too many requests."""
|
|
24
|
-
def __init__(self, message: str, aws_info: dict = None):
|
|
25
|
-
super().__init__(message, 429, aws_info)
|
|
26
|
-
|
|
27
|
-
class InternalServerError(MeteocatAPIError):
|
|
28
|
-
"""Error 500: Internal server error."""
|
|
29
|
-
def __init__(self, message: str, aws_info: dict = None):
|
|
30
|
-
super().__init__(message, 500, aws_info)
|
|
31
|
-
|
|
32
|
-
class UnknownAPIError(MeteocatAPIError):
|
|
33
|
-
"""Error desconocido de la API."""
|
|
34
|
-
def __init__(self, message: str, status_code: int, aws_info: dict = None):
|
|
35
|
-
super().__init__(message, status_code, aws_info)
|
|
1
|
+
"""METEOCAT API exceptions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
class MeteocatAPIError(Exception):
|
|
6
|
+
"""Clase base para todos los errores de la API de Meteocat."""
|
|
7
|
+
def __init__(self, message: str, status_code: int, aws_info: dict = None):
|
|
8
|
+
super().__init__(message)
|
|
9
|
+
self.status_code = status_code
|
|
10
|
+
self.aws_info = aws_info
|
|
11
|
+
|
|
12
|
+
class BadRequestError(MeteocatAPIError):
|
|
13
|
+
"""Error 400: Bad request."""
|
|
14
|
+
def __init__(self, message: str, aws_info: dict = None):
|
|
15
|
+
super().__init__(message, 400, aws_info)
|
|
16
|
+
|
|
17
|
+
class ForbiddenError(MeteocatAPIError):
|
|
18
|
+
"""Error 403: Forbidden."""
|
|
19
|
+
def __init__(self, message: str, aws_info: dict = None):
|
|
20
|
+
super().__init__(message, 403, aws_info)
|
|
21
|
+
|
|
22
|
+
class TooManyRequestsError(MeteocatAPIError):
|
|
23
|
+
"""Error 429: Too many requests."""
|
|
24
|
+
def __init__(self, message: str, aws_info: dict = None):
|
|
25
|
+
super().__init__(message, 429, aws_info)
|
|
26
|
+
|
|
27
|
+
class InternalServerError(MeteocatAPIError):
|
|
28
|
+
"""Error 500: Internal server error."""
|
|
29
|
+
def __init__(self, message: str, aws_info: dict = None):
|
|
30
|
+
super().__init__(message, 500, aws_info)
|
|
31
|
+
|
|
32
|
+
class UnknownAPIError(MeteocatAPIError):
|
|
33
|
+
"""Error desconocido de la API."""
|
|
34
|
+
def __init__(self, message: str, status_code: int, aws_info: dict = None):
|
|
35
|
+
super().__init__(message, status_code, aws_info)
|