inepandas

inepandas - A Python wrapper for the Spanish National Statistics Institute (INE) API.

This package provides convenient access to all statistical data and metadata published by the Instituto Nacional de Estadística (INE) of Spain.

Basic usage:

>>> import inepandas
>>>
>>> # Get available operations
>>> operations = inepandas.get_operations()
>>>
>>> # Get CPI data
>>> cpi = inepandas.get_table_data(50902, nlast=5)
>>>
>>> # Get specific series
>>> series = inepandas.get_series_data("IPC251856", nlast=12)

For more control, use the INEClient directly:

>>> from inepandas import INEClient
>>>
>>> with INEClient(language="EN") as client:
...     ops = inepandas.get_operations(client=client)
 1"""
 2inepandas - A Python wrapper for the Spanish National Statistics Institute (INE) API.
 3
 4This package provides convenient access to all statistical data and metadata
 5published by the Instituto Nacional de Estadística (INE) of Spain.
 6
 7Basic usage:
 8
 9    >>> import inepandas
10    >>>
11    >>> # Get available operations
12    >>> operations = inepandas.get_operations()
13    >>>
14    >>> # Get CPI data
15    >>> cpi = inepandas.get_table_data(50902, nlast=5)
16    >>>
17    >>> # Get specific series
18    >>> series = inepandas.get_series_data("IPC251856", nlast=12)
19
20For more control, use the INEClient directly:
21
22    >>> from inepandas import INEClient
23    >>>
24    >>> with INEClient(language="EN") as client:
25    ...     ops = inepandas.get_operations(client=client)
26"""
27
28from .client import INEClient
29from .data import get_operation_data, get_series_data, get_table_data
30from .exceptions import (
31    APIError,
32    DataParsingError,
33    NotFoundError,
34    PyINEError,
35    RateLimitError,
36    ValidationError,
37)
38from .metadata import (
39    get_classifications,
40    get_operation,
41    get_operations,
42    get_periodicities,
43    get_publications,
44    get_series_metadata,
45    get_series_values,
46    get_table_group_values,
47    get_table_groups,
48    get_table_series,
49    get_tables,
50    get_values,
51    get_variables,
52)
53
54__version__ = "0.1.0"
55
56__all__ = [
57    # Version
58    "__version__",
59    # Client
60    "INEClient",
61    # Data functions
62    "get_table_data",
63    "get_series_data",
64    "get_operation_data",
65    # Metadata functions
66    "get_operations",
67    "get_operation",
68    "get_variables",
69    "get_values",
70    "get_tables",
71    "get_table_groups",
72    "get_table_group_values",
73    "get_table_series",
74    "get_series_metadata",
75    "get_series_values",
76    "get_periodicities",
77    "get_publications",
78    "get_classifications",
79    # Exceptions
80    "PyINEError",
81    "APIError",
82    "NotFoundError",
83    "RateLimitError",
84    "ValidationError",
85    "DataParsingError",
86]
__version__ = '0.1.0'
class INEClient:
 21class INEClient:
 22    """
 23    HTTP client for communicating with the INE JSON API.
 24
 25    This class handles all HTTP communication with the INE API,
 26    including request construction, error handling, and response parsing.
 27
 28    Parameters
 29    ----------
 30    language : str, optional
 31        Language for API responses. Either "ES" (Spanish) or "EN" (English).
 32        Defaults to "ES".
 33    timeout : int, optional
 34        Request timeout in seconds. Defaults to 30.
 35
 36    Examples
 37    --------
 38    >>> client = INEClient()
 39    >>> operations = client.get("OPERACIONES_DISPONIBLES")
 40
 41    >>> client = INEClient(language="EN")
 42    >>> operations = client.get("OPERACIONES_DISPONIBLES")
 43    """
 44
 45    def __init__(
 46        self,
 47        language: str = "ES",
 48        timeout: int = DEFAULT_TIMEOUT,
 49    ) -> None:
 50        if language.upper() not in LANGUAGES:
 51            raise ValueError(f"Language must be one of {LANGUAGES}, got '{language}'")
 52
 53        self.language = language.upper()
 54        self.timeout = timeout
 55        self._session = requests.Session()
 56        self._session.headers.update(
 57            {
 58                "Accept": "application/json",
 59                "User-Agent": "inepandas/0.1.0",
 60            }
 61        )
 62
 63    def _build_url(
 64        self,
 65        function: str,
 66        input_id: str | int | None = None,
 67        params: dict[str, Any] | None = None,
 68    ) -> str:
 69        """
 70        Build the full URL for an API request.
 71
 72        Parameters
 73        ----------
 74        function : str
 75            The API function name (e.g., "DATOS_TABLA", "OPERACIONES_DISPONIBLES").
 76        input_id : str | int | None, optional
 77            The input identifier for the function.
 78        params : dict[str, Any] | None, optional
 79            Query parameters to include in the URL.
 80
 81        Returns
 82        -------
 83        str
 84            The complete URL for the API request.
 85        """
 86        url_parts = [BASE_URL, self.language, function]
 87
 88        if input_id is not None:
 89            url_parts.append(str(input_id))
 90
 91        url = "/".join(url_parts)
 92
 93        if params:
 94            # Filter out None values and convert to string
 95            filtered_params = {
 96                k: str(v) for k, v in params.items() if v is not None
 97            }
 98            if filtered_params:
 99                url = f"{url}?{urlencode(filtered_params)}"
100
101        return url
102
103    def get(
104        self,
105        function: str,
106        input_id: str | int | None = None,
107        **params: Any,
108    ) -> Any:
109        """
110        Make a GET request to the INE API.
111
112        Parameters
113        ----------
114        function : str
115            The API function name.
116        input_id : str | int | None, optional
117            The input identifier for the function.
118        **params : Any
119            Additional query parameters.
120
121        Returns
122        -------
123        Any
124            The parsed JSON response.
125
126        Raises
127        ------
128        NotFoundError
129            If the requested resource is not found (404).
130        RateLimitError
131            If the API rate limit is exceeded (429).
132        APIError
133            For other API errors.
134        """
135        url = self._build_url(function, input_id, params if params else None)
136
137        try:
138            response = self._session.get(url, timeout=self.timeout)
139        except requests.exceptions.Timeout as e:
140            raise APIError(f"Request timed out after {self.timeout} seconds") from e
141        except requests.exceptions.ConnectionError as e:
142            raise APIError(f"Connection error: {e}") from e
143        except requests.exceptions.RequestException as e:
144            raise APIError(f"Request failed: {e}") from e
145
146        return self._handle_response(response)
147
148    def _handle_response(self, response: requests.Response) -> Any:
149        """
150        Handle the API response and raise appropriate exceptions.
151
152        Parameters
153        ----------
154        response : requests.Response
155            The response object from the request.
156
157        Returns
158        -------
159        Any
160            The parsed JSON response.
161
162        Raises
163        ------
164        NotFoundError
165            If the resource is not found (404).
166        RateLimitError
167            If rate limit is exceeded (429).
168        APIError
169            For other HTTP errors.
170        """
171        if response.status_code == 404:
172            raise NotFoundError(
173                f"Resource not found: {response.url}",
174                status_code=404,
175            )
176
177        if response.status_code == 429:
178            raise RateLimitError(
179                "API rate limit exceeded. Please try again later.",
180                status_code=429,
181            )
182
183        if response.status_code >= 400:
184            raise APIError(
185                f"API error: {response.status_code} - {response.text}",
186                status_code=response.status_code,
187            )
188
189        try:
190            return response.json()
191        except ValueError as e:
192            raise APIError(f"Failed to parse JSON response: {e}") from e
193
194    def close(self) -> None:
195        """Close the HTTP session."""
196        self._session.close()
197
198    def __enter__(self) -> "INEClient":
199        """Context manager entry."""
200        return self
201
202    def __exit__(self, *args: Any) -> None:
203        """Context manager exit."""
204        self.close()

HTTP client for communicating with the INE JSON API.

This class handles all HTTP communication with the INE API, including request construction, error handling, and response parsing.

Parameters

language : str, optional Language for API responses. Either "ES" (Spanish) or "EN" (English). Defaults to "ES". timeout : int, optional Request timeout in seconds. Defaults to 30.

Examples

>>> client = INEClient()
>>> operations = client.get("OPERACIONES_DISPONIBLES")
>>> client = INEClient(language="EN")
>>> operations = client.get("OPERACIONES_DISPONIBLES")
INEClient(language: str = 'ES', timeout: int = 30)
45    def __init__(
46        self,
47        language: str = "ES",
48        timeout: int = DEFAULT_TIMEOUT,
49    ) -> None:
50        if language.upper() not in LANGUAGES:
51            raise ValueError(f"Language must be one of {LANGUAGES}, got '{language}'")
52
53        self.language = language.upper()
54        self.timeout = timeout
55        self._session = requests.Session()
56        self._session.headers.update(
57            {
58                "Accept": "application/json",
59                "User-Agent": "inepandas/0.1.0",
60            }
61        )
language
timeout
def get( self, function: str, input_id: str | int | None = None, **params: Any) -> Any:
103    def get(
104        self,
105        function: str,
106        input_id: str | int | None = None,
107        **params: Any,
108    ) -> Any:
109        """
110        Make a GET request to the INE API.
111
112        Parameters
113        ----------
114        function : str
115            The API function name.
116        input_id : str | int | None, optional
117            The input identifier for the function.
118        **params : Any
119            Additional query parameters.
120
121        Returns
122        -------
123        Any
124            The parsed JSON response.
125
126        Raises
127        ------
128        NotFoundError
129            If the requested resource is not found (404).
130        RateLimitError
131            If the API rate limit is exceeded (429).
132        APIError
133            For other API errors.
134        """
135        url = self._build_url(function, input_id, params if params else None)
136
137        try:
138            response = self._session.get(url, timeout=self.timeout)
139        except requests.exceptions.Timeout as e:
140            raise APIError(f"Request timed out after {self.timeout} seconds") from e
141        except requests.exceptions.ConnectionError as e:
142            raise APIError(f"Connection error: {e}") from e
143        except requests.exceptions.RequestException as e:
144            raise APIError(f"Request failed: {e}") from e
145
146        return self._handle_response(response)

Make a GET request to the INE API.

Parameters

function : str The API function name. input_id : str | int | None, optional The input identifier for the function. **params : Any Additional query parameters.

Returns

Any The parsed JSON response.

Raises

NotFoundError If the requested resource is not found (404). RateLimitError If the API rate limit is exceeded (429). APIError For other API errors.

def close(self) -> None:
194    def close(self) -> None:
195        """Close the HTTP session."""
196        self._session.close()

Close the HTTP session.

def get_table_data( table_id: int, client: INEClient | None = None, nlast: int | None = None, date_start: str | None = None, date_end: str | None = None, detail: int = 0, friendly: bool = True, metadata: bool = False, filters: dict[int, int] | None = None) -> pandas.core.frame.DataFrame:
137def get_table_data(
138    table_id: int,
139    client: INEClient | None = None,
140    nlast: int | None = None,
141    date_start: str | None = None,
142    date_end: str | None = None,
143    detail: int = 0,
144    friendly: bool = True,
145    metadata: bool = False,
146    filters: dict[int, int] | None = None,
147) -> pd.DataFrame:
148    """
149    Get data from a statistical table.
150
151    Parameters
152    ----------
153    table_id : int
154        The table identifier.
155    client : INEClient | None, optional
156        An existing INEClient instance.
157    nlast : int | None, optional
158        Number of last periods to retrieve.
159    date_start : str | None, optional
160        Start date in format "YYYY/MM/DD" or "YYYYMMDD".
161    date_end : str | None, optional
162        End date in format "YYYY/MM/DD" or "YYYYMMDD".
163    detail : int, optional
164        Level of detail (0, 1, or 2).
165    friendly : bool, optional
166        Whether to use friendly output format. Defaults to True.
167    metadata : bool, optional
168        Whether to include metadata. Defaults to False.
169    filters : dict[int, int] | None, optional
170        Dictionary mapping variable IDs to value IDs for filtering.
171        Example: {115: 29} filters to province Madrid (variable 115, value 29).
172
173    Returns
174    -------
175    pd.DataFrame
176        DataFrame with the table data.
177
178    Examples
179    --------
180    >>> # Get last 5 periods of CPI table
181    >>> df = get_table_data(50902, nlast=5)
182
183    >>> # Get data for 2024
184    >>> df = get_table_data(50902, date_start="2024/01/01", date_end="2024/12/31")
185
186    >>> # Get data filtered by province
187    >>> df = get_table_data(50913, nlast=1, filters={70: 9027})  # Catalonia
188    """
189    _client = client or INEClient()
190
191    # Build parameters
192    params: dict[str, Any] = {"det": detail}
193
194    if nlast is not None:
195        params["nult"] = nlast
196
197    date_param = _parse_date_param(date_start, date_end)
198    if date_param:
199        params["date"] = date_param
200
201    # Build tip parameter
202    tip_parts = []
203    if friendly:
204        tip_parts.append("A")
205    if metadata:
206        tip_parts.append("M")
207    if tip_parts:
208        params["tip"] = "".join(tip_parts)
209
210    # Add filters
211    if filters:
212        for var_id, val_id in filters.items():
213            params[f"tv"] = f"{var_id}:{val_id}"
214
215    try:
216        data = _client.get("DATOS_TABLA", table_id, **params)
217    finally:
218        if client is None:
219            _client.close()
220
221    if not data:
222        return pd.DataFrame()
223
224    # Flatten and process the data
225    df = _flatten_series_data(data)
226    df = _process_dataframe(df)
227
228    return df

Get data from a statistical table.

Parameters

table_id : int The table identifier. client : INEClient | None, optional An existing INEClient instance. nlast : int | None, optional Number of last periods to retrieve. date_start : str | None, optional Start date in format "YYYY/MM/DD" or "YYYYMMDD". date_end : str | None, optional End date in format "YYYY/MM/DD" or "YYYYMMDD". detail : int, optional Level of detail (0, 1, or 2). friendly : bool, optional Whether to use friendly output format. Defaults to True. metadata : bool, optional Whether to include metadata. Defaults to False. filters : dict[int, int] | None, optional Dictionary mapping variable IDs to value IDs for filtering. Example: {115: 29} filters to province Madrid (variable 115, value 29).

Returns

pd.DataFrame DataFrame with the table data.

Examples

>>> # Get last 5 periods of CPI table
>>> df = get_table_data(50902, nlast=5)
>>> # Get data for 2024
>>> df = get_table_data(50902, date_start="2024/01/01", date_end="2024/12/31")
>>> # Get data filtered by province
>>> df = get_table_data(50913, nlast=1, filters={70: 9027})  # Catalonia
def get_series_data( series_code: str, client: INEClient | None = None, nlast: int | None = None, date_start: str | None = None, date_end: str | None = None, detail: int = 0, friendly: bool = True, metadata: bool = False) -> pandas.core.frame.DataFrame:
231def get_series_data(
232    series_code: str,
233    client: INEClient | None = None,
234    nlast: int | None = None,
235    date_start: str | None = None,
236    date_end: str | None = None,
237    detail: int = 0,
238    friendly: bool = True,
239    metadata: bool = False,
240) -> pd.DataFrame:
241    """
242    Get data from a specific series.
243
244    Parameters
245    ----------
246    series_code : str
247        The series code (e.g., "IPC251856").
248    client : INEClient | None, optional
249        An existing INEClient instance.
250    nlast : int | None, optional
251        Number of last periods to retrieve.
252    date_start : str | None, optional
253        Start date in format "YYYY/MM/DD" or "YYYYMMDD".
254    date_end : str | None, optional
255        End date in format "YYYY/MM/DD" or "YYYYMMDD".
256    detail : int, optional
257        Level of detail (0, 1, or 2).
258    friendly : bool, optional
259        Whether to use friendly output format. Defaults to True.
260    metadata : bool, optional
261        Whether to include metadata. Defaults to False.
262
263    Returns
264    -------
265    pd.DataFrame
266        DataFrame with the series data.
267
268    Examples
269    --------
270    >>> # Get last 12 months of CPI annual variation
271    >>> df = get_series_data("IPC251856", nlast=12)
272
273    >>> # Get 2023 data
274    >>> df = get_series_data("IPC251856", date_start="2023/01/01", date_end="2023/12/31")
275    """
276    _client = client or INEClient()
277
278    # Build parameters
279    params: dict[str, Any] = {"det": detail}
280
281    if nlast is not None:
282        params["nult"] = nlast
283
284    date_param = _parse_date_param(date_start, date_end)
285    if date_param:
286        params["date"] = date_param
287
288    # Build tip parameter
289    tip_parts = []
290    if friendly:
291        tip_parts.append("A")
292    if metadata:
293        tip_parts.append("M")
294    if tip_parts:
295        params["tip"] = "".join(tip_parts)
296
297    try:
298        data = _client.get("DATOS_SERIE", series_code, **params)
299    finally:
300        if client is None:
301            _client.close()
302
303    if not data:
304        return pd.DataFrame()
305
306    # Series data comes as a single object with nested Data
307    if isinstance(data, dict):
308        data = [data]
309
310    df = _flatten_series_data(data)
311    df = _process_dataframe(df)
312
313    return df

Get data from a specific series.

Parameters

series_code : str The series code (e.g., "IPC251856"). client : INEClient | None, optional An existing INEClient instance. nlast : int | None, optional Number of last periods to retrieve. date_start : str | None, optional Start date in format "YYYY/MM/DD" or "YYYYMMDD". date_end : str | None, optional End date in format "YYYY/MM/DD" or "YYYYMMDD". detail : int, optional Level of detail (0, 1, or 2). friendly : bool, optional Whether to use friendly output format. Defaults to True. metadata : bool, optional Whether to include metadata. Defaults to False.

Returns

pd.DataFrame DataFrame with the series data.

Examples

>>> # Get last 12 months of CPI annual variation
>>> df = get_series_data("IPC251856", nlast=12)
>>> # Get 2023 data
>>> df = get_series_data("IPC251856", date_start="2023/01/01", date_end="2023/12/31")
def get_operation_data( operation: str | int, client: INEClient | None = None, periodicity: int | None = None, nlast: int | None = None, detail: int = 0, friendly: bool = True, metadata: bool = False, **filters: int | None) -> pandas.core.frame.DataFrame:
316def get_operation_data(
317    operation: str | int,
318    client: INEClient | None = None,
319    periodicity: int | None = None,
320    nlast: int | None = None,
321    detail: int = 0,
322    friendly: bool = True,
323    metadata: bool = False,
324    **filters: int | None,
325) -> pd.DataFrame:
326    """
327    Get data from an operation using metadata filters.
328
329    This function allows flexible querying of operation data by
330    specifying variable-value pairs as filters.
331
332    Parameters
333    ----------
334    operation : str | int
335        The operation identifier (e.g., "IPC" or 25).
336    client : INEClient | None, optional
337        An existing INEClient instance.
338    periodicity : int | None, optional
339        Periodicity ID (1=monthly, 3=quarterly, 6=semi-annual, 12=annual).
340    nlast : int | None, optional
341        Number of last periods to retrieve.
342    detail : int, optional
343        Level of detail (0, 1, or 2).
344    friendly : bool, optional
345        Whether to use friendly output format. Defaults to True.
346    metadata : bool, optional
347        Whether to include metadata. Defaults to False.
348    **filters : int | None
349        Filter groups as g1, g2, g3, etc.
350        Format: g1="variable_id:value_id" or g1="variable_id:" for all values.
351
352    Returns
353    -------
354    pd.DataFrame
355        DataFrame with the filtered operation data.
356
357    Examples
358    --------
359    >>> # Get CPI monthly variation for Madrid province, all ECOICOP groups
360    >>> df = get_operation_data(
361    ...     "IPC",
362    ...     periodicity=1,
363    ...     nlast=1,
364    ...     g1="115:29",    # Province: Madrid
365    ...     g2="3:84",      # Data type: monthly variation
366    ...     g3="762:",      # ECOICOP groups: all
367    ... )
368    """
369    _client = client or INEClient()
370
371    params: dict[str, Any] = {"det": detail}
372
373    if periodicity is not None:
374        params["p"] = periodicity
375
376    if nlast is not None:
377        params["nult"] = nlast
378
379    # Build tip parameter
380    tip_parts = []
381    if friendly:
382        tip_parts.append("A")
383    if metadata:
384        tip_parts.append("M")
385    if tip_parts:
386        params["tip"] = "".join(tip_parts)
387
388    # Add filter groups
389    for key, value in filters.items():
390        if value is not None:
391            params[key] = value
392
393    try:
394        data = _client.get("DATOS_METADATAOPERACION", operation, **params)
395    finally:
396        if client is None:
397            _client.close()
398
399    if not data:
400        return pd.DataFrame()
401
402    df = _flatten_series_data(data)
403    df = _process_dataframe(df)
404
405    return df

Get data from an operation using metadata filters.

This function allows flexible querying of operation data by specifying variable-value pairs as filters.

Parameters

operation : str | int The operation identifier (e.g., "IPC" or 25). client : INEClient | None, optional An existing INEClient instance. periodicity : int | None, optional Periodicity ID (1=monthly, 3=quarterly, 6=semi-annual, 12=annual). nlast : int | None, optional Number of last periods to retrieve. detail : int, optional Level of detail (0, 1, or 2). friendly : bool, optional Whether to use friendly output format. Defaults to True. metadata : bool, optional Whether to include metadata. Defaults to False. **filters : int | None Filter groups as g1, g2, g3, etc. Format: g1="variable_id:value_id" or g1="variable_id:" for all values.

Returns

pd.DataFrame DataFrame with the filtered operation data.

Examples

>>> # Get CPI monthly variation for Madrid province, all ECOICOP groups
>>> df = get_operation_data(
...     "IPC",
...     periodicity=1,
...     nlast=1,
...     g1="115:29",    # Province: Madrid
...     g2="3:84",      # Data type: monthly variation
...     g3="762:",      # ECOICOP groups: all
... )
def get_operations( client: INEClient | None = None, detail: int = 0, geo: int | None = None) -> pandas.core.frame.DataFrame:
11def get_operations(
12    client: INEClient | None = None,
13    detail: int = 0,
14    geo: int | None = None,
15) -> pd.DataFrame:
16    """
17    Get all available statistical operations.
18
19    Parameters
20    ----------
21    client : INEClient | None, optional
22        An existing INEClient instance. If None, creates a new one.
23    detail : int, optional
24        Level of detail (0, 1, or 2). Defaults to 0.
25    geo : int | None, optional
26        Geographic scope filter:
27        - None: all operations
28        - 0: national results only
29        - 1: regional/provincial/municipal results
30
31    Returns
32    -------
33    pd.DataFrame
34        DataFrame with columns: Id, Cod_IOE, Nombre, Codigo, Url (if available)
35
36    Examples
37    --------
38    >>> ops = get_operations()
39    >>> ops.head()
40    """
41    _client = client or INEClient()
42
43    params: dict[str, Any] = {"det": detail}
44    if geo is not None:
45        params["geo"] = geo
46
47    data = _client.get("OPERACIONES_DISPONIBLES", **params)
48
49    if client is None:
50        _client.close()
51
52    return pd.DataFrame(data)

Get all available statistical operations.

Parameters

client : INEClient | None, optional An existing INEClient instance. If None, creates a new one. detail : int, optional Level of detail (0, 1, or 2). Defaults to 0. geo : int | None, optional Geographic scope filter: - None: all operations - 0: national results only - 1: regional/provincial/municipal results

Returns

pd.DataFrame DataFrame with columns: Id, Cod_IOE, Nombre, Codigo, Url (if available)

Examples

>>> ops = get_operations()
>>> ops.head()
def get_operation( operation: str | int, client: INEClient | None = None, detail: int = 0) -> pandas.core.frame.DataFrame:
55def get_operation(
56    operation: str | int,
57    client: INEClient | None = None,
58    detail: int = 0,
59) -> pd.DataFrame:
60    """
61    Get information about a specific operation.
62
63    Parameters
64    ----------
65    operation : str | int
66        Operation identifier. Can be:
67        - Numeric ID (e.g., 25)
68        - Alphabetic code (e.g., "IPC")
69        - IOE code (e.g., "IOE30138")
70    client : INEClient | None, optional
71        An existing INEClient instance.
72    detail : int, optional
73        Level of detail (0, 1, or 2).
74
75    Returns
76    -------
77    pd.DataFrame
78        DataFrame with operation information.
79    """
80    _client = client or INEClient()
81
82    data = _client.get("OPERACION", operation, det=detail)
83
84    if client is None:
85        _client.close()
86
87    # API returns a single object, wrap in list for DataFrame
88    if isinstance(data, dict):
89        data = [data]
90
91    return pd.DataFrame(data)

Get information about a specific operation.

Parameters

operation : str | int Operation identifier. Can be: - Numeric ID (e.g., 25) - Alphabetic code (e.g., "IPC") - IOE code (e.g., "IOE30138") client : INEClient | None, optional An existing INEClient instance. detail : int, optional Level of detail (0, 1, or 2).

Returns

pd.DataFrame DataFrame with operation information.

def get_variables( client: INEClient | None = None, operation: str | int | None = None) -> pandas.core.frame.DataFrame:
 94def get_variables(
 95    client: INEClient | None = None,
 96    operation: str | int | None = None,
 97) -> pd.DataFrame:
 98    """
 99    Get available variables, optionally filtered by operation.
100
101    Parameters
102    ----------
103    client : INEClient | None, optional
104        An existing INEClient instance.
105    operation : str | int | None, optional
106        If provided, only return variables used in this operation.
107
108    Returns
109    -------
110    pd.DataFrame
111        DataFrame with columns: Id, Nombre, Codigo
112    """
113    _client = client or INEClient()
114
115    if operation is not None:
116        data = _client.get("VARIABLES_OPERACION", operation)
117    else:
118        data = _client.get("VARIABLES")
119
120    if client is None:
121        _client.close()
122
123    return pd.DataFrame(data)

Get available variables, optionally filtered by operation.

Parameters

client : INEClient | None, optional An existing INEClient instance. operation : str | int | None, optional If provided, only return variables used in this operation.

Returns

pd.DataFrame DataFrame with columns: Id, Nombre, Codigo

def get_values( variable: int, client: INEClient | None = None, operation: str | int | None = None, detail: int = 0) -> pandas.core.frame.DataFrame:
126def get_values(
127    variable: int,
128    client: INEClient | None = None,
129    operation: str | int | None = None,
130    detail: int = 0,
131) -> pd.DataFrame:
132    """
133    Get all values for a specific variable.
134
135    Parameters
136    ----------
137    variable : int
138        The variable ID.
139    client : INEClient | None, optional
140        An existing INEClient instance.
141    operation : str | int | None, optional
142        If provided, only return values used in this operation.
143    detail : int, optional
144        Level of detail (0, 1, or 2).
145
146    Returns
147    -------
148    pd.DataFrame
149        DataFrame with columns: Id, Fk_Variable, Nombre, Codigo
150    """
151    _client = client or INEClient()
152
153    if operation is not None:
154        data = _client.get(
155            "VALORES_VARIABLEOPERACION",
156            f"{variable}/{operation}",
157            det=detail,
158        )
159    else:
160        data = _client.get("VALORES_VARIABLE", variable, det=detail)
161
162    if client is None:
163        _client.close()
164
165    return pd.DataFrame(data)

Get all values for a specific variable.

Parameters

variable : int The variable ID. client : INEClient | None, optional An existing INEClient instance. operation : str | int | None, optional If provided, only return values used in this operation. detail : int, optional Level of detail (0, 1, or 2).

Returns

pd.DataFrame DataFrame with columns: Id, Fk_Variable, Nombre, Codigo

def get_tables( operation: str | int, client: INEClient | None = None, detail: int = 0, geo: int | None = None) -> pandas.core.frame.DataFrame:
168def get_tables(
169    operation: str | int,
170    client: INEClient | None = None,
171    detail: int = 0,
172    geo: int | None = None,
173) -> pd.DataFrame:
174    """
175    Get all tables for a specific operation.
176
177    Parameters
178    ----------
179    operation : str | int
180        The operation identifier.
181    client : INEClient | None, optional
182        An existing INEClient instance.
183    detail : int, optional
184        Level of detail (0, 1, or 2).
185    geo : int | None, optional
186        Geographic scope filter (0=national, 1=regional).
187
188    Returns
189    -------
190    pd.DataFrame
191        DataFrame with table information.
192    """
193    _client = client or INEClient()
194
195    params: dict[str, Any] = {"det": detail}
196    if geo is not None:
197        params["geo"] = geo
198
199    data = _client.get("TABLAS_OPERACION", operation, **params)
200
201    if client is None:
202        _client.close()
203
204    return pd.DataFrame(data)

Get all tables for a specific operation.

Parameters

operation : str | int The operation identifier. client : INEClient | None, optional An existing INEClient instance. detail : int, optional Level of detail (0, 1, or 2). geo : int | None, optional Geographic scope filter (0=national, 1=regional).

Returns

pd.DataFrame DataFrame with table information.

def get_table_groups( table_id: int, client: INEClient | None = None) -> pandas.core.frame.DataFrame:
207def get_table_groups(
208    table_id: int,
209    client: INEClient | None = None,
210) -> pd.DataFrame:
211    """
212    Get the selection groups (combos) that define a table.
213
214    Parameters
215    ----------
216    table_id : int
217        The table identifier.
218    client : INEClient | None, optional
219        An existing INEClient instance.
220
221    Returns
222    -------
223    pd.DataFrame
224        DataFrame with columns: Id, Nombre
225    """
226    _client = client or INEClient()
227
228    data = _client.get("GRUPOS_TABLA", table_id)
229
230    if client is None:
231        _client.close()
232
233    return pd.DataFrame(data)

Get the selection groups (combos) that define a table.

Parameters

table_id : int The table identifier. client : INEClient | None, optional An existing INEClient instance.

Returns

pd.DataFrame DataFrame with columns: Id, Nombre

def get_table_group_values( table_id: int, group_id: int, client: INEClient | None = None, detail: int = 0) -> pandas.core.frame.DataFrame:
236def get_table_group_values(
237    table_id: int,
238    group_id: int,
239    client: INEClient | None = None,
240    detail: int = 0,
241) -> pd.DataFrame:
242    """
243    Get all values for a specific group within a table.
244
245    Parameters
246    ----------
247    table_id : int
248        The table identifier.
249    group_id : int
250        The group identifier.
251    client : INEClient | None, optional
252        An existing INEClient instance.
253    detail : int, optional
254        Level of detail (0, 1, or 2).
255
256    Returns
257    -------
258    pd.DataFrame
259        DataFrame with value information.
260    """
261    _client = client or INEClient()
262
263    data = _client.get(
264        "VALORES_GRUPOSTABLA",
265        f"{table_id}/{group_id}",
266        det=detail,
267    )
268
269    if client is None:
270        _client.close()
271
272    return pd.DataFrame(data)

Get all values for a specific group within a table.

Parameters

table_id : int The table identifier. group_id : int The group identifier. client : INEClient | None, optional An existing INEClient instance. detail : int, optional Level of detail (0, 1, or 2).

Returns

pd.DataFrame DataFrame with value information.

def get_table_series( table_id: int, client: INEClient | None = None, detail: int = 0) -> pandas.core.frame.DataFrame:
342def get_table_series(
343    table_id: int,
344    client: INEClient | None = None,
345    detail: int = 0,
346) -> pd.DataFrame:
347    """
348    Get all series contained in a table.
349
350    Parameters
351    ----------
352    table_id : int
353        The table identifier.
354    client : INEClient | None, optional
355        An existing INEClient instance.
356    detail : int, optional
357        Level of detail (0, 1, or 2).
358
359    Returns
360    -------
361    pd.DataFrame
362        DataFrame with series information.
363    """
364    _client = client or INEClient()
365
366    data = _client.get("SERIES_TABLA", table_id, det=detail)
367
368    if client is None:
369        _client.close()
370
371    return pd.DataFrame(data)

Get all series contained in a table.

Parameters

table_id : int The table identifier. client : INEClient | None, optional An existing INEClient instance. detail : int, optional Level of detail (0, 1, or 2).

Returns

pd.DataFrame DataFrame with series information.

def get_series_metadata( series_code: str, client: INEClient | None = None, detail: int = 0) -> pandas.core.frame.DataFrame:
275def get_series_metadata(
276    series_code: str,
277    client: INEClient | None = None,
278    detail: int = 0,
279) -> pd.DataFrame:
280    """
281    Get metadata for a specific series.
282
283    Parameters
284    ----------
285    series_code : str
286        The series code (e.g., "IPC251856").
287    client : INEClient | None, optional
288        An existing INEClient instance.
289    detail : int, optional
290        Level of detail (0, 1, or 2).
291
292    Returns
293    -------
294    pd.DataFrame
295        DataFrame with series metadata.
296    """
297    _client = client or INEClient()
298
299    data = _client.get("SERIE", series_code, det=detail)
300
301    if client is None:
302        _client.close()
303
304    if isinstance(data, dict):
305        data = [data]
306
307    return pd.DataFrame(data)

Get metadata for a specific series.

Parameters

series_code : str The series code (e.g., "IPC251856"). client : INEClient | None, optional An existing INEClient instance. detail : int, optional Level of detail (0, 1, or 2).

Returns

pd.DataFrame DataFrame with series metadata.

def get_series_values( series_code: str, client: INEClient | None = None, detail: int = 0) -> pandas.core.frame.DataFrame:
310def get_series_values(
311    series_code: str,
312    client: INEClient | None = None,
313    detail: int = 0,
314) -> pd.DataFrame:
315    """
316    Get the variables and values that define a series.
317
318    Parameters
319    ----------
320    series_code : str
321        The series code (e.g., "IPC251856").
322    client : INEClient | None, optional
323        An existing INEClient instance.
324    detail : int, optional
325        Level of detail (0, 1, or 2).
326
327    Returns
328    -------
329    pd.DataFrame
330        DataFrame with the values defining the series.
331    """
332    _client = client or INEClient()
333
334    data = _client.get("VALORES_SERIE", series_code, det=detail)
335
336    if client is None:
337        _client.close()
338
339    return pd.DataFrame(data)

Get the variables and values that define a series.

Parameters

series_code : str The series code (e.g., "IPC251856"). client : INEClient | None, optional An existing INEClient instance. detail : int, optional Level of detail (0, 1, or 2).

Returns

pd.DataFrame DataFrame with the values defining the series.

def get_periodicities( client: INEClient | None = None) -> pandas.core.frame.DataFrame:
374def get_periodicities(
375    client: INEClient | None = None,
376) -> pd.DataFrame:
377    """
378    Get all available periodicities.
379
380    Common periodicities:
381    - 1: monthly
382    - 3: quarterly
383    - 6: semi-annual
384    - 12: annual
385
386    Parameters
387    ----------
388    client : INEClient | None, optional
389        An existing INEClient instance.
390
391    Returns
392    -------
393    pd.DataFrame
394        DataFrame with columns: Id, Nombre, Codigo
395    """
396    _client = client or INEClient()
397
398    data = _client.get("PERIODICIDADES")
399
400    if client is None:
401        _client.close()
402
403    return pd.DataFrame(data)

Get all available periodicities.

Common periodicities:

  • 1: monthly
  • 3: quarterly
  • 6: semi-annual
  • 12: annual

Parameters

client : INEClient | None, optional An existing INEClient instance.

Returns

pd.DataFrame DataFrame with columns: Id, Nombre, Codigo

def get_publications( client: INEClient | None = None, operation: str | int | None = None, detail: int = 0) -> pandas.core.frame.DataFrame:
406def get_publications(
407    client: INEClient | None = None,
408    operation: str | int | None = None,
409    detail: int = 0,
410) -> pd.DataFrame:
411    """
412    Get available publications, optionally filtered by operation.
413
414    Parameters
415    ----------
416    client : INEClient | None, optional
417        An existing INEClient instance.
418    operation : str | int | None, optional
419        If provided, only return publications for this operation.
420    detail : int, optional
421        Level of detail (0, 1, or 2).
422
423    Returns
424    -------
425    pd.DataFrame
426        DataFrame with publication information.
427    """
428    _client = client or INEClient()
429
430    if operation is not None:
431        data = _client.get("PUBLICACIONES_OPERACION", operation, det=detail)
432    else:
433        data = _client.get("PUBLICACIONES", det=detail)
434
435    if client is None:
436        _client.close()
437
438    return pd.DataFrame(data)

Get available publications, optionally filtered by operation.

Parameters

client : INEClient | None, optional An existing INEClient instance. operation : str | int | None, optional If provided, only return publications for this operation. detail : int, optional Level of detail (0, 1, or 2).

Returns

pd.DataFrame DataFrame with publication information.

def get_classifications( client: INEClient | None = None, operation: str | int | None = None) -> pandas.core.frame.DataFrame:
441def get_classifications(
442    client: INEClient | None = None,
443    operation: str | int | None = None,
444) -> pd.DataFrame:
445    """
446    Get available classifications, optionally filtered by operation.
447
448    Parameters
449    ----------
450    client : INEClient | None, optional
451        An existing INEClient instance.
452    operation : str | int | None, optional
453        If provided, only return classifications for this operation.
454
455    Returns
456    -------
457    pd.DataFrame
458        DataFrame with classification information.
459    """
460    _client = client or INEClient()
461
462    if operation is not None:
463        data = _client.get("CLASIFICACIONES_OPERACION", operation)
464    else:
465        data = _client.get("CLASIFICACIONES")
466
467    if client is None:
468        _client.close()
469
470    return pd.DataFrame(data)

Get available classifications, optionally filtered by operation.

Parameters

client : INEClient | None, optional An existing INEClient instance. operation : str | int | None, optional If provided, only return classifications for this operation.

Returns

pd.DataFrame DataFrame with classification information.

class PyINEError(builtins.Exception):
5class PyINEError(Exception):
6    """Base exception for all pyine errors."""
7
8    pass

Base exception for all pyine errors.

class APIError(inepandas.PyINEError):
11class APIError(PyINEError):
12    """Raised when the INE API returns an error response."""
13
14    def __init__(self, message: str, status_code: int | None = None) -> None:
15        self.status_code = status_code
16        super().__init__(message)

Raised when the INE API returns an error response.

APIError(message: str, status_code: int | None = None)
14    def __init__(self, message: str, status_code: int | None = None) -> None:
15        self.status_code = status_code
16        super().__init__(message)
status_code
class NotFoundError(inepandas.APIError):
19class NotFoundError(APIError):
20    """Raised when a requested resource is not found (404)."""
21
22    pass

Raised when a requested resource is not found (404).

class RateLimitError(inepandas.APIError):
25class RateLimitError(APIError):
26    """Raised when API rate limit is exceeded."""
27
28    pass

Raised when API rate limit is exceeded.

class ValidationError(inepandas.PyINEError):
31class ValidationError(PyINEError):
32    """Raised when input validation fails."""
33
34    pass

Raised when input validation fails.

class DataParsingError(inepandas.PyINEError):
37class DataParsingError(PyINEError):
38    """Raised when response data cannot be parsed."""
39
40    pass

Raised when response data cannot be parsed.