Skip to content

Commit d00e2f9

Browse files
authored
Patch 0.1.9, solving instabilities
This is an emergency patch. Unfortunately, the API version previously used by the package started to be disabled by the Ipea servers in Brasilia and will eventually be completely discontinued. To keep the package working, I was forced to use the most up-to-date version of the API (http://www.ipeadata.gov.br/api/odata4/). Paradoxically, this newer version returns much less information than the old version. Because of this, some functionality previously existing in some functions of the package had to be sacrificed: i) the new version of the API does not allow the existence of the sources() function. The function has been kept in the package using the old version of the API, but it is subject to instabilities and can be completely broken at any time; ii) the themes() function no longer returns the "MACRO", "REGIONAL" and "SOCIAL" indicator columns; iii) the timeseries() function no longer has the "groupby" option.
1 parent 3613378 commit d00e2f9

10 files changed

+63
-47
lines changed

ipeadatapy/api_call.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ def api_call(api):
1212
return data_frame
1313
except Exception:
1414
return None
15-
return None
15+
return None

ipeadatapy/countries.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33

44
def countries(country_id=None, keyword=None):
55
"""Returns all Ipeadata available countries and country IDs."""
6-
api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/Paises"
7-
cReturn = api_call(api)[['PAICODIGO','PAINOME']].rename(index=str, columns={"PAICODIGO": "ID", "PAINOME": "COUNTRY"})
6+
# api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/Paises" # DEPRECATED.
7+
api = "http://ipeadata.gov.br/api/odata4/Paises"
8+
call = api_call(api)
9+
10+
cReturn = call[['PAICODIGO','PAINOME']].rename(index=str, columns={"PAICODIGO": "ID", "PAINOME": "COUNTRY"})
811
if country_id is not None:
912
cReturn = cReturn.loc[cReturn["ID"] == country_id]
1013
if keyword is not None:

ipeadatapy/describe.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44

55
def describe(series):
66
"""Describes the specified time series. series must be the time series' code."""
7-
desc_df = pd.DataFrame({list(metadata(series)['NAME'])[0]: [list(metadata(series)['NAME'])[0], list(metadata(series)['CODE'])[0], list(metadata_old(series)['BIG THEME'])[0], list(metadata_old(series)['THEME'])[0], list(metadata(series)['SOURCE'])[0], list(metadata(series)['SOURCE ACRONYM'])[0], list(metadata(series)['COMMENT'])[0], list(metadata(series)['LAST UPDATE'])[0], list(metadata(series)['FREQUENCY'])[0], list(metadata(series)['MEASURE'])[0], list(metadata(series)['UNIT'])[0], list(metadata(series)['SERIES STATUS'])[0]]}, index=['Name', 'Code', 'Big Theme', 'Theme', 'Source', 'Source acronym', 'Comment', 'Last update', 'Frequency', 'Measure', 'Unit', 'Status'])
7+
series_metadata = metadata(series)
8+
desc_df = pd.DataFrame({list(series_metadata['NAME'])[0]: [list(series_metadata['NAME'])[0], list(series_metadata['CODE'])[0], list(series_metadata['BIG THEME'])[0], list(series_metadata['THEME CODE'])[0], list(series_metadata['SOURCE'])[0], list(series_metadata['SOURCE ACRONYM'])[0], list(series_metadata['COMMENT'])[0], list(series_metadata['LAST UPDATE'])[0], list(series_metadata['FREQUENCY'])[0], list(series_metadata['MEASURE'])[0], list(series_metadata['UNIT'])[0], list(series_metadata['SERIES STATUS'])[0]]}, index=['Name', 'Code', 'Big Theme', 'Theme code', 'Source', 'Source acronym', 'Comment', 'Last update', 'Frequency', 'Measure', 'Unit', 'Status'])
89
return desc_df

ipeadatapy/latest_updates.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ def latest_updates():
77
#num_of_updated_series = list(df_latest_updates['LAST UPDATE'].str.contains('2019-03-22')).count(True)
88
#print('Number of series updated today:')
99
#print(num_of_updated_series)
10-
return df_latest_updates
10+
return df_latest_updates

ipeadatapy/list_series.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ def list_series(keyword=None, code=None, name=None):
2323
df_f = df[df['NAME'].str.contains(keyword)]
2424
else:
2525
df_f = df
26-
return df_f
26+
return df_f

ipeadatapy/metadata_old.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import pandas as pd
22
from .api_call import api_call
33

4-
def metadata_old(series=None):
4+
def metadata_old(series=None): # DEPRECATED.
55
"""If no keyword is specified, returns a data frame containing all Ipeadata's time series. Else, returns only the ones that contains the specified keyword in their names."""
66
url_final = "('%s')" % series if series is not None else ""
7-
api = "http://www.ipeadata.gov.br/api/v1/Metadados%s" % url_final
7+
api = "http://www.ipeadata.gov.br/api/v1/Metadados%s" % url_final # DEPRECATED.
88
return api_call(api).rename(index=str, columns={"TEMNOME": "THEME", "BASNOME": "BIG THEME", "FNTNOME": "SOURCE", "FNTSIGLA": "SOURCE ACRONYM", "FNTURL": "SOURCE URL", "MULNOME": "UNIT", "PAICODIGO": "COUNTRY", "PERNOME": "FREQUENCY", "SERATUALIZACAO": "LAST UPDATE", "SERCODIGO": "CODE", "SERCOMENTARIO": "COMMENT", "SERNOME": "NAME", "SERNUMERICA": "NUMERICA", "SERSTATUS": "SERIES STATUS", "TEMCODIGO": "THEME CODE", "UNINOME": "MEASURE"})

ipeadatapy/sources.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import pandas as pd
22
from .api_call import api_call
33

4-
def sources():
5-
"""Returns available Ipeadata's sources in the form of a data frame."""
6-
api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/Fontes"
4+
def sources(): # DEPRECATED.
5+
"""(!) DEPRECATED. Returns available Ipeadata's sources in the form of a data frame."""
6+
# api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/Fontes" # DEPRECATED.
7+
api = "http://ipeadata.gov.br/api/v1/Fontes"
78
return api_call(api).rename(index=str, columns={"FNTID": "ID", "FNTSIGLA": "SIGLA"})['SIGLA']
9+

ipeadatapy/territories.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ def territories(name=None, level=None, territory_id=None, area=None, areaGreater
2020
:return: Returns available Ipeadata territories.
2121
:rtype: pandas.DataFrame
2222
"""
23-
api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/Territorios"
24-
tReturn = api_call(api)[['TERNOME', 'TERCODIGO', 'NIVNOME', 'TERAREA','TERCAPITAL']].rename(index=str, columns={"TERNOME": "NAME", "TERCODIGO": "ID","NIVNOME": "LEVEL","TERAREA": "AREA", "TERCAPITAL": "CAPITAL"})
23+
# api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/Territorios" # DEPRECATED.
24+
api = "http://ipeadata.gov.br/api/odata4/Territorios"
25+
call = api_call(api)
26+
27+
tReturn = call[['TERNOME', 'TERCODIGO', 'NIVNOME', 'TERAREA','TERCAPITAL']].rename(index=str, columns={"TERNOME": "NAME", "TERCODIGO": "ID","NIVNOME": "LEVEL","TERAREA": "AREA", "TERCAPITAL": "CAPITAL"})
2528
if name is not None:
2629
tReturn = tReturn.loc[tReturn["NAME"] == name]
2730
if level is not None:

ipeadatapy/themes.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,25 @@ def themes(theme_id=None, name=None, macro=None, regional=None, social=None):
1616
:return: Returns available Ipeadata themes
1717
:rtype: pandas.DataFrame
1818
"""
19-
api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/Temas"
20-
thReturn = api_call(api)[['TEMCODIGO','TEMNOME','MACRO','REGIONAL','SOCIAL']].rename(index=str, columns={"TEMCODIGO": "ID", "TEMNOME": "NAME"})
19+
20+
api = "http://ipeadata.gov.br/api/odata4/Temas" # Unfortunately, this API version do not return "MACRO", "REGIONAL" and "SOCIAL" indicators..
21+
# api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/Temas" # DEPRECATED.
22+
# api = "http://ipeadata.gov.br/api/v1/Temas" # DEPRECATED.
23+
24+
# thReturn = api_call(api)[['TEMCODIGO','TEMNOME','MACRO','REGIONAL','SOCIAL']].rename(index=str, columns={"TEMCODIGO": "ID", "TEMNOME": "NAME"})
25+
thReturn = api_call(api)[['TEMCODIGO','TEMNOME']].rename(index=str, columns={"TEMCODIGO": "ID", "TEMNOME": "NAME"})
26+
2127
if theme_id is not None:
2228
thReturn = thReturn.loc[thReturn["ID"] == theme_id]
2329
if name is not None:
2430
thReturn = thReturn.loc[thReturn["NAME"] == name]
25-
if macro is not None:
26-
thReturn = thReturn.loc[thReturn["MACRO"] == macro]
27-
if regional is not None:
28-
thReturn = thReturn.loc[thReturn["REGIONAL"] == regional]
29-
if social is not None:
30-
thReturn = thReturn.loc[thReturn["SOCIAL"] == social]
31+
32+
# DEPRECATED:
33+
# if macro is not None:
34+
# thReturn = thReturn.loc[thReturn["MACRO"] == macro]
35+
# if regional is not None:
36+
# thReturn = thReturn.loc[thReturn["REGIONAL"] == regional]
37+
# if social is not None:
38+
# thReturn = thReturn.loc[thReturn["SOCIAL"] == social]
39+
3140
return thReturn

ipeadatapy/timeseries.py

+24-26
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import pandas as pd
22
from .api_call import api_call
33
from .metadata_old import metadata_old
4+
from .metadata import metadata
45

5-
def timeseries(series, groupby=None, year=None, yearGreaterThan=None, yearSmallerThan=None, day=None, dayGreaterThan=None, daySmallerThan=None, month=None, monthGreaterThan=None, monthSmallerThan=None, code=None, date=None):
6+
def timeseries(series, year=None, yearGreaterThan=None, yearSmallerThan=None, day=None, dayGreaterThan=None, daySmallerThan=None, month=None, monthGreaterThan=None, monthSmallerThan=None, code=None, date=None):
67
"""
78
Returns the specified time series' data values. `series` must be a time series code
89
:param series: Time series code. For the available time series run list_series()
910
:type series: str
10-
:param groupby: Grouping criteria
11-
:type groupby: str, optional
1211
:param year: Year which the data set will be restricted to.
1312
:type year: int, optional
1413
:param yearGreaterThan: Year which the data set will be restricted to years strictly greater.
@@ -34,27 +33,31 @@ def timeseries(series, groupby=None, year=None, yearGreaterThan=None, yearSmalle
3433
:return: Returns the data series for the specified time series.
3534
:rtype: pandas.DataFrame
3635
"""
37-
if groupby is not None:
38-
df = get_nivel_region(series)
39-
if df['NIVNOME'].isin([groupby]).any():
40-
api = ("http://ipeadata2-homologa.ipea.gov.br/api/v1/AnoValors"
41-
"(SERCODIGO='{}',NIVNOME='{}')?$top=100&$skip=0&$orderby"
42-
"=SERATUALIZACAO&$count=true").format(series, groupby)
43-
return api_call(api)
44-
return None
45-
api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/ValoresSerie(SERCODIGO='%s')" % series
36+
37+
# api = "http://ipeadata2-homologa.ipea.gov.br/api/v1/ValoresSerie(SERCODIGO='%s')" % series # DEPRECATED.
38+
# api = "http://ipeadata.gov.br/api/v1/ValoresSerie(SERCODIGO='%s')" % series # DEPRECATED.
39+
api = "http://ipeadata.gov.br/api/odata4/ValoresSerie(SERCODIGO='%s')" % series
40+
series_metadata = metadata(series)
41+
call = api_call(api)
4642

47-
if list(metadata_old(series)['BIG THEME']) == ['Regional']:
48-
if list(metadata_old(series)['MEASURE'])[0] is not None:
49-
ts_df = api_call(api).rename(index=str, columns={"SERCODIGO": "CODE", "VALDATA": "DATE", "VALVALOR": "VALUE ("+list(metadata_old(series)['MEASURE'])[0]+")"})
43+
if list(series_metadata['BIG THEME']) == ['Regional']:
44+
if list(series_metadata['MEASURE'])[0] is not None:
45+
ts_df = call.rename(index=str, columns={"SERCODIGO": "CODE", "VALDATA": "DATE", "VALVALOR": "VALUE ("+list(series_metadata['MEASURE'])[0]+")"})
5046
else:
51-
ts_df = api_call(api).rename(index=str, columns={"SERCODIGO": "CODE", "VALDATA": "DATE", "VALVALOR": "VALUE"})
52-
elif list(metadata_old(series)['MEASURE'])[0] is not None:
53-
ts_df = api_call(api)[['ANO','DIA','MES','SERCODIGO','VALDATA','VALVALOR']].rename(index=str, columns={"ANO": "YEAR", "DIA": "DAY", "MES": "MONTH", "SERCODIGO": "CODE", "VALDATA": "DATE", "VALVALOR": "VALUE ("+list(metadata_old(series)['MEASURE'])[0]+")"})
54-
#api_call(api).rename(index=str, columns={"SERCODIGO": "CODIGO", "VALDATA": "DATA", "VALVALOR": "VALOR ("+list(metadata_old(series)['UNINOME'])[0]+")"})
47+
ts_df = call.rename(index=str, columns={"SERCODIGO": "CODE", "VALDATA": "DATE", "VALVALOR": "VALUE"})
48+
elif list(series_metadata['MEASURE'])[0] is not None:
49+
ts_df = call[['SERCODIGO','VALDATA','VALVALOR']].rename(index=str, columns={"SERCODIGO": "CODE", "VALDATA": "DATE", "VALVALOR": "VALUE ("+list(series_metadata['MEASURE'])[0]+")"})
5550
else:
56-
ts_df = api_call(api)[['ANO','DIA','MES','SERCODIGO','VALDATA','VALVALOR']].rename(index=str, columns={"ANO": "YEAR", "DIA": "DAY", "MES": "MONTH", "SERCODIGO": "CODE", "VALDATA": "DATE", "VALVALOR": "VALUE"})
51+
ts_df = call[['SERCODIGO','VALDATA','VALVALOR']].rename(index=str, columns={"SERCODIGO": "CODE", "VALDATA": "DATE", "VALVALOR": "VALUE"})
5752

53+
ts_df.rename(columns={'DATE':'RAW DATE'}, inplace=True)
54+
ts_df['DATE'] = ts_df['RAW DATE'].str[0:10]
55+
ts_df['DATE'] = pd.to_datetime(ts_df["DATE"])
56+
ts_df['YEAR'] = pd.DatetimeIndex(ts_df['DATE']).year
57+
ts_df['DAY'] = pd.DatetimeIndex(ts_df['DATE']).day
58+
ts_df['MONTH'] = pd.DatetimeIndex(ts_df['DATE']).month
59+
ts_df = ts_df.set_index(['DATE']).iloc[:,[0,1,4,5,3,2]]
60+
5861
if year is not None:
5962
ts_df = ts_df.loc[ts_df["YEAR"] == year]
6063
if yearGreaterThan is not None:
@@ -76,12 +79,7 @@ def timeseries(series, groupby=None, year=None, yearGreaterThan=None, yearSmalle
7679
if code is not None:
7780
ts_df = ts_df.loc[ts_df["CODE"] == code]
7881
if date is not None:
79-
ts_df = ts_df.loc[ts_df["DATE"] == date]
80-
81-
ts_df.rename(columns={'DATE':'RAW DATE'}, inplace=True)
82-
ts_df['DATE'] = ts_df['RAW DATE'].str[0:10]
83-
ts_df["DATE"] = pd.to_datetime(ts_df["DATE"])
84-
ts_df = ts_df.set_index(['DATE'])
82+
ts_df = ts_df.loc[ts_df["RAW DATE"] == date]
8583

8684
return ts_df
8785

0 commit comments

Comments
 (0)