pydeflate 2.2.0__tar.gz → 2.3.0__tar.gz

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.
Files changed (34) hide show
  1. {pydeflate-2.2.0 → pydeflate-2.3.0}/PKG-INFO +133 -1
  2. {pydeflate-2.2.0 → pydeflate-2.3.0}/README.md +132 -0
  3. {pydeflate-2.2.0 → pydeflate-2.3.0}/pyproject.toml +6 -1
  4. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/__init__.py +29 -1
  5. pydeflate-2.3.0/src/pydeflate/deflate/get_deflators.py +233 -0
  6. pydeflate-2.3.0/src/pydeflate/exchange/get_rates.py +207 -0
  7. {pydeflate-2.2.0 → pydeflate-2.3.0}/LICENSE +0 -0
  8. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/.pydeflate_data/README.md +0 -0
  9. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/cache.py +0 -0
  10. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/constants.py +0 -0
  11. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/context.py +0 -0
  12. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/core/__init__.py +0 -0
  13. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/core/api.py +0 -0
  14. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/core/deflator.py +0 -0
  15. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/core/exchange.py +0 -0
  16. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/core/source.py +0 -0
  17. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/deflate/__init__.py +0 -0
  18. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/deflate/deflators.py +0 -0
  19. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/deflate/legacy_deflate.py +0 -0
  20. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/exceptions.py +0 -0
  21. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/exchange/__init__.py +0 -0
  22. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/exchange/exchangers.py +0 -0
  23. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/plugins.py +0 -0
  24. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/protocols.py +0 -0
  25. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/pydeflate_config.py +0 -0
  26. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/schemas.py +0 -0
  27. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/settings/emu.json +0 -0
  28. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/settings/oecd_codes.json +0 -0
  29. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/sources/__init__.py +0 -0
  30. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/sources/common.py +0 -0
  31. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/sources/dac.py +0 -0
  32. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/sources/imf.py +0 -0
  33. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/sources/world_bank.py +0 -0
  34. {pydeflate-2.2.0 → pydeflate-2.3.0}/src/pydeflate/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydeflate
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Package to convert current prices figures to constant prices and vice versa
5
5
  Author: Jorge Rivera
6
6
  Author-email: Jorge Rivera <Jorge.Rivera@one.org>
@@ -28,6 +28,7 @@ Description-Content-Type: text/markdown
28
28
  [![pypi](https://img.shields.io/pypi/v/pydeflate.svg)](https://pypi.python.org/pypi/pydeflate)
29
29
  [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
30
30
  [![Downloads](https://pepy.tech/badge/pydeflate/month)](https://pepy.tech/project/pydeflate)
31
+ [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue)](https://jm-rivera.github.io/pydeflate/)
31
32
 
32
33
  **pydeflate** is a Python package to:
33
34
  - Convert current price data to constant prices.
@@ -36,6 +37,8 @@ Description-Content-Type: text/markdown
36
37
 
37
38
  When converting to or from constant prices, it takes into account changes in prices and exchange rates over time. This allows for accurate comparisons across years, countries, and currencies.
38
39
 
40
+ 📚 **[Read the full documentation →](https://jm-rivera.github.io/pydeflate/)**
41
+
39
42
  ## Important Note
40
43
 
41
44
  **pydeflate v2 has recently been released. It includes api changes which break backwards-compatibility**. While a version of the `deflate` function is still available, it is now deprecated and will be removed in future versions. Please use the new deflator functions for improved simplicity, clarity and performance.
@@ -58,6 +61,11 @@ When converting to or from constant prices, it takes into account changes in pri
58
61
  - [Currency Conversion](#currency-conversion)
59
62
  - [Example](#example-currency-conversion)
60
63
 
64
+ - [Getting Deflators and Exchange Rates Directly](#getting-deflators-and-exchange-rates-directly)
65
+ - [Getting Deflators](#getting-deflators)
66
+ - [Getting Exchange Rates](#getting-exchange-rates)
67
+ - [Common Use Cases](#common-use-cases)
68
+
61
69
  - [Example: Using Source-Specific Codes](#example-using-source-specific-codes)
62
70
 
63
71
  - [Data Sources and Method Options](#data-sources-and-method-options)
@@ -182,6 +190,111 @@ df_can = oecd_dac_exchange(
182
190
  )
183
191
  ```
184
192
 
193
+ ## Getting Deflators and Exchange Rates Directly
194
+
195
+ **New in v2.3.0**: You can now retrieve deflator and exchange rate data directly as DataFrames, without needing to provide your own data. This is useful for inspecting deflators, analyzing trends, or pre-computing values for later use.
196
+
197
+ ### Getting Deflators
198
+
199
+ ```python
200
+ from pydeflate import get_imf_gdp_deflators, set_pydeflate_path
201
+
202
+ # Specify the path where deflator data will be saved
203
+ set_pydeflate_path("path/to/data/folder")
204
+
205
+ # Get deflators for specific countries and years
206
+ deflators = get_imf_gdp_deflators(
207
+ base_year=2015,
208
+ source_currency="USA",
209
+ target_currency="EUR",
210
+ countries=["USA", "FRA", "GBR"], # Optional: filter specific countries
211
+ years=range(2010, 2024), # Optional: filter specific years
212
+ )
213
+
214
+ # Returns a DataFrame with columns: iso_code, year, deflator
215
+ print(deflators.head())
216
+ ```
217
+
218
+ You can also get the individual components that make up the deflator:
219
+
220
+ ```python
221
+ # Include price deflator, exchange deflator, and exchange rate components
222
+ deflators_detailed = get_imf_gdp_deflators(
223
+ base_year=2015,
224
+ source_currency="USA",
225
+ target_currency="EUR",
226
+ include_components=True, # Adds price_deflator, exchange_deflator, exchange_rate columns
227
+ )
228
+ ```
229
+
230
+ ### Available Get Deflator Functions
231
+
232
+ - `get_imf_gdp_deflators`: Get IMF GDP deflators
233
+ - `get_imf_cpi_deflators`: Get IMF CPI deflators
234
+ - `get_imf_cpi_e_deflators`: Get IMF end-of-period CPI deflators
235
+ - `get_wb_gdp_deflators`: Get World Bank GDP deflators
236
+ - `get_wb_gdp_linked_deflators`: Get World Bank linked GDP deflators
237
+ - `get_wb_cpi_deflators`: Get World Bank CPI deflators
238
+ - `get_oecd_dac_deflators`: Get OECD DAC deflators
239
+
240
+ ### Getting Exchange Rates
241
+
242
+ ```python
243
+ from pydeflate import get_imf_exchange_rates
244
+
245
+ # Get exchange rates for specific currency pairs
246
+ rates = get_imf_exchange_rates(
247
+ source_currency="USD",
248
+ target_currency="EUR",
249
+ countries=["USA", "FRA", "GBR"], # Optional: filter specific countries
250
+ years=range(2010, 2024), # Optional: filter specific years
251
+ )
252
+
253
+ # Returns a DataFrame with columns: iso_code, year, exchange_rate
254
+ print(rates.head())
255
+ ```
256
+
257
+ ### Available Get Exchange Rate Functions
258
+
259
+ - `get_imf_exchange_rates`: Get IMF exchange rates
260
+ - `get_wb_exchange_rates`: Get World Bank exchange rates
261
+ - `get_wb_ppp_rates`: Get World Bank PPP conversion rates
262
+ - `get_oecd_dac_exchange_rates`: Get OECD DAC exchange rates
263
+
264
+ ### Common Use Cases
265
+
266
+ **Analyzing deflator trends:**
267
+ ```python
268
+ import matplotlib.pyplot as plt
269
+
270
+ # Get US GDP deflators over time
271
+ deflators = get_imf_gdp_deflators(
272
+ base_year=2015,
273
+ countries=["USA"],
274
+ years=range(2000, 2024)
275
+ )
276
+
277
+ plt.plot(deflators["year"], deflators["deflator"])
278
+ plt.title("US GDP Deflator (Base Year 2015)")
279
+ plt.show()
280
+ ```
281
+
282
+ **Pre-computing deflators for manual calculations:**
283
+ ```python
284
+ # Get deflators
285
+ deflators = get_imf_gdp_deflators(
286
+ base_year=2020,
287
+ source_currency="USA",
288
+ target_currency="EUR"
289
+ )
290
+
291
+ # Use in your own calculations
292
+ my_value_2021 = 100 # USD in 2021
293
+ deflator_2021 = deflators[(deflators["iso_code"] == "USA") &
294
+ (deflators["year"] == 2021)]["deflator"].iloc[0]
295
+ constant_value = my_value_2021 / deflator_2021
296
+ ```
297
+
185
298
  ## Example: Using Source-Specific Codes
186
299
 
187
300
  If your data uses source-specific country codes (e.g., DAC codes), set use_source_codes=True and specify the appropriate id_column.
@@ -383,3 +496,22 @@ This is useful for:
383
496
  - Customizing logging verbosity
384
497
  - Testing with temporary cache directories
385
498
 
499
+ ## Documentation
500
+
501
+ For comprehensive documentation including detailed examples, advanced features, and troubleshooting:
502
+
503
+ **[📚 Full Documentation](https://jm-rivera.github.io/pydeflate/)**
504
+
505
+ The documentation includes:
506
+ - [Getting Started Guide](https://jm-rivera.github.io/pydeflate/getting-started/) - Setup and DataFrame requirements
507
+ - [Deflation Guide](https://jm-rivera.github.io/pydeflate/deflation/) - All deflation methods with examples
508
+ - [Currency Exchange](https://jm-rivera.github.io/pydeflate/exchange/) - Currency conversion examples
509
+ - [Data Sources](https://jm-rivera.github.io/pydeflate/data-sources/) - IMF, World Bank, and OECD DAC comparison
510
+ - [Advanced Topics](https://jm-rivera.github.io/pydeflate/advanced/exceptions/) - Error handling, contexts, plugins, validation
511
+ - [Migration Guide](https://jm-rivera.github.io/pydeflate/migration/) - v1 to v2 migration
512
+ - [FAQ](https://jm-rivera.github.io/pydeflate/faq/) - Common questions and troubleshooting
513
+
514
+ ## Contributing
515
+
516
+ Contributions are welcome! Please feel free to submit a Pull Request or open an issue on [GitHub](https://github.com/jm-rivera/pydeflate).
517
+
@@ -3,6 +3,7 @@
3
3
  [![pypi](https://img.shields.io/pypi/v/pydeflate.svg)](https://pypi.python.org/pypi/pydeflate)
4
4
  [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
5
5
  [![Downloads](https://pepy.tech/badge/pydeflate/month)](https://pepy.tech/project/pydeflate)
6
+ [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue)](https://jm-rivera.github.io/pydeflate/)
6
7
 
7
8
  **pydeflate** is a Python package to:
8
9
  - Convert current price data to constant prices.
@@ -11,6 +12,8 @@
11
12
 
12
13
  When converting to or from constant prices, it takes into account changes in prices and exchange rates over time. This allows for accurate comparisons across years, countries, and currencies.
13
14
 
15
+ 📚 **[Read the full documentation →](https://jm-rivera.github.io/pydeflate/)**
16
+
14
17
  ## Important Note
15
18
 
16
19
  **pydeflate v2 has recently been released. It includes api changes which break backwards-compatibility**. While a version of the `deflate` function is still available, it is now deprecated and will be removed in future versions. Please use the new deflator functions for improved simplicity, clarity and performance.
@@ -33,6 +36,11 @@ When converting to or from constant prices, it takes into account changes in pri
33
36
  - [Currency Conversion](#currency-conversion)
34
37
  - [Example](#example-currency-conversion)
35
38
 
39
+ - [Getting Deflators and Exchange Rates Directly](#getting-deflators-and-exchange-rates-directly)
40
+ - [Getting Deflators](#getting-deflators)
41
+ - [Getting Exchange Rates](#getting-exchange-rates)
42
+ - [Common Use Cases](#common-use-cases)
43
+
36
44
  - [Example: Using Source-Specific Codes](#example-using-source-specific-codes)
37
45
 
38
46
  - [Data Sources and Method Options](#data-sources-and-method-options)
@@ -157,6 +165,111 @@ df_can = oecd_dac_exchange(
157
165
  )
158
166
  ```
159
167
 
168
+ ## Getting Deflators and Exchange Rates Directly
169
+
170
+ **New in v2.3.0**: You can now retrieve deflator and exchange rate data directly as DataFrames, without needing to provide your own data. This is useful for inspecting deflators, analyzing trends, or pre-computing values for later use.
171
+
172
+ ### Getting Deflators
173
+
174
+ ```python
175
+ from pydeflate import get_imf_gdp_deflators, set_pydeflate_path
176
+
177
+ # Specify the path where deflator data will be saved
178
+ set_pydeflate_path("path/to/data/folder")
179
+
180
+ # Get deflators for specific countries and years
181
+ deflators = get_imf_gdp_deflators(
182
+ base_year=2015,
183
+ source_currency="USA",
184
+ target_currency="EUR",
185
+ countries=["USA", "FRA", "GBR"], # Optional: filter specific countries
186
+ years=range(2010, 2024), # Optional: filter specific years
187
+ )
188
+
189
+ # Returns a DataFrame with columns: iso_code, year, deflator
190
+ print(deflators.head())
191
+ ```
192
+
193
+ You can also get the individual components that make up the deflator:
194
+
195
+ ```python
196
+ # Include price deflator, exchange deflator, and exchange rate components
197
+ deflators_detailed = get_imf_gdp_deflators(
198
+ base_year=2015,
199
+ source_currency="USA",
200
+ target_currency="EUR",
201
+ include_components=True, # Adds price_deflator, exchange_deflator, exchange_rate columns
202
+ )
203
+ ```
204
+
205
+ ### Available Get Deflator Functions
206
+
207
+ - `get_imf_gdp_deflators`: Get IMF GDP deflators
208
+ - `get_imf_cpi_deflators`: Get IMF CPI deflators
209
+ - `get_imf_cpi_e_deflators`: Get IMF end-of-period CPI deflators
210
+ - `get_wb_gdp_deflators`: Get World Bank GDP deflators
211
+ - `get_wb_gdp_linked_deflators`: Get World Bank linked GDP deflators
212
+ - `get_wb_cpi_deflators`: Get World Bank CPI deflators
213
+ - `get_oecd_dac_deflators`: Get OECD DAC deflators
214
+
215
+ ### Getting Exchange Rates
216
+
217
+ ```python
218
+ from pydeflate import get_imf_exchange_rates
219
+
220
+ # Get exchange rates for specific currency pairs
221
+ rates = get_imf_exchange_rates(
222
+ source_currency="USD",
223
+ target_currency="EUR",
224
+ countries=["USA", "FRA", "GBR"], # Optional: filter specific countries
225
+ years=range(2010, 2024), # Optional: filter specific years
226
+ )
227
+
228
+ # Returns a DataFrame with columns: iso_code, year, exchange_rate
229
+ print(rates.head())
230
+ ```
231
+
232
+ ### Available Get Exchange Rate Functions
233
+
234
+ - `get_imf_exchange_rates`: Get IMF exchange rates
235
+ - `get_wb_exchange_rates`: Get World Bank exchange rates
236
+ - `get_wb_ppp_rates`: Get World Bank PPP conversion rates
237
+ - `get_oecd_dac_exchange_rates`: Get OECD DAC exchange rates
238
+
239
+ ### Common Use Cases
240
+
241
+ **Analyzing deflator trends:**
242
+ ```python
243
+ import matplotlib.pyplot as plt
244
+
245
+ # Get US GDP deflators over time
246
+ deflators = get_imf_gdp_deflators(
247
+ base_year=2015,
248
+ countries=["USA"],
249
+ years=range(2000, 2024)
250
+ )
251
+
252
+ plt.plot(deflators["year"], deflators["deflator"])
253
+ plt.title("US GDP Deflator (Base Year 2015)")
254
+ plt.show()
255
+ ```
256
+
257
+ **Pre-computing deflators for manual calculations:**
258
+ ```python
259
+ # Get deflators
260
+ deflators = get_imf_gdp_deflators(
261
+ base_year=2020,
262
+ source_currency="USA",
263
+ target_currency="EUR"
264
+ )
265
+
266
+ # Use in your own calculations
267
+ my_value_2021 = 100 # USD in 2021
268
+ deflator_2021 = deflators[(deflators["iso_code"] == "USA") &
269
+ (deflators["year"] == 2021)]["deflator"].iloc[0]
270
+ constant_value = my_value_2021 / deflator_2021
271
+ ```
272
+
160
273
  ## Example: Using Source-Specific Codes
161
274
 
162
275
  If your data uses source-specific country codes (e.g., DAC codes), set use_source_codes=True and specify the appropriate id_column.
@@ -358,3 +471,22 @@ This is useful for:
358
471
  - Customizing logging verbosity
359
472
  - Testing with temporary cache directories
360
473
 
474
+ ## Documentation
475
+
476
+ For comprehensive documentation including detailed examples, advanced features, and troubleshooting:
477
+
478
+ **[📚 Full Documentation](https://jm-rivera.github.io/pydeflate/)**
479
+
480
+ The documentation includes:
481
+ - [Getting Started Guide](https://jm-rivera.github.io/pydeflate/getting-started/) - Setup and DataFrame requirements
482
+ - [Deflation Guide](https://jm-rivera.github.io/pydeflate/deflation/) - All deflation methods with examples
483
+ - [Currency Exchange](https://jm-rivera.github.io/pydeflate/exchange/) - Currency conversion examples
484
+ - [Data Sources](https://jm-rivera.github.io/pydeflate/data-sources/) - IMF, World Bank, and OECD DAC comparison
485
+ - [Advanced Topics](https://jm-rivera.github.io/pydeflate/advanced/exceptions/) - Error handling, contexts, plugins, validation
486
+ - [Migration Guide](https://jm-rivera.github.io/pydeflate/migration/) - v1 to v2 migration
487
+ - [FAQ](https://jm-rivera.github.io/pydeflate/faq/) - Common questions and troubleshooting
488
+
489
+ ## Contributing
490
+
491
+ Contributions are welcome! Please feel free to submit a Pull Request or open an issue on [GitHub](https://github.com/jm-rivera/pydeflate).
492
+
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pydeflate"
3
- version = "2.2.0"
3
+ version = "2.3.0"
4
4
  description = "Package to convert current prices figures to constant prices and vice versa"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -30,6 +30,11 @@ dev = [
30
30
  "pytest-cov>=7.0.0",
31
31
  "ruff>=0.13.3",
32
32
  ]
33
+ docs = [
34
+ "mkdocs-material>=9.5.0",
35
+ "mkdocs-minify-plugin>=0.8.0",
36
+ "mkdocstrings[python]>=0.26.0",
37
+ ]
33
38
 
34
39
  [project.urls]
35
40
  Homepage = "https://github.com/jm-rivera/pydeflate"
@@ -1,5 +1,5 @@
1
1
  __author__ = """Jorge Rivera"""
2
- __version__ = "2.2.0"
2
+ __version__ = "2.3.0"
3
3
 
4
4
  from pydeflate.deflate.deflators import (
5
5
  imf_cpi_deflate,
@@ -10,6 +10,15 @@ from pydeflate.deflate.deflators import (
10
10
  wb_gdp_deflate,
11
11
  wb_gdp_linked_deflate,
12
12
  )
13
+ from pydeflate.deflate.get_deflators import (
14
+ get_imf_cpi_deflators,
15
+ get_imf_cpi_e_deflators,
16
+ get_imf_gdp_deflators,
17
+ get_oecd_dac_deflators,
18
+ get_wb_cpi_deflators,
19
+ get_wb_gdp_deflators,
20
+ get_wb_gdp_linked_deflators,
21
+ )
13
22
  from pydeflate.deflate.legacy_deflate import deflate
14
23
  from pydeflate.exchange.exchangers import (
15
24
  imf_exchange,
@@ -17,6 +26,12 @@ from pydeflate.exchange.exchangers import (
17
26
  wb_exchange,
18
27
  wb_exchange_ppp,
19
28
  )
29
+ from pydeflate.exchange.get_rates import (
30
+ get_imf_exchange_rates,
31
+ get_oecd_dac_exchange_rates,
32
+ get_wb_exchange_rates,
33
+ get_wb_ppp_rates,
34
+ )
20
35
  from pydeflate.pydeflate_config import set_data_dir, setup_logger
21
36
 
22
37
  from pydeflate.context import (
@@ -60,11 +75,24 @@ __all__ = [
60
75
  "wb_cpi_deflate",
61
76
  "wb_gdp_deflate",
62
77
  "wb_gdp_linked_deflate",
78
+ # Get deflators functions
79
+ "get_imf_cpi_deflators",
80
+ "get_imf_cpi_e_deflators",
81
+ "get_imf_gdp_deflators",
82
+ "get_oecd_dac_deflators",
83
+ "get_wb_cpi_deflators",
84
+ "get_wb_gdp_deflators",
85
+ "get_wb_gdp_linked_deflators",
63
86
  # Exchange functions
64
87
  "imf_exchange",
65
88
  "oecd_dac_exchange",
66
89
  "wb_exchange",
67
90
  "wb_exchange_ppp",
91
+ # Get exchange rates functions
92
+ "get_imf_exchange_rates",
93
+ "get_oecd_dac_exchange_rates",
94
+ "get_wb_exchange_rates",
95
+ "get_wb_ppp_rates",
68
96
  # Configuration
69
97
  "set_pydeflate_path",
70
98
  "setup_logger",
@@ -0,0 +1,233 @@
1
+ from functools import wraps
2
+
3
+ import pandas as pd
4
+
5
+ from pydeflate.core.api import BaseDeflate
6
+ from pydeflate.core.source import DAC, IMF, WorldBank
7
+
8
+
9
+ def _generate_get_deflator_docstring(source_name: str, price_kind: str) -> str:
10
+ """Generate docstring for each get deflator function."""
11
+ return (
12
+ f"Get deflator data from {source_name} ({price_kind}) without requiring user data.\n\n"
13
+ f"This function returns a DataFrame containing deflator values for the specified parameters.\n\n"
14
+ "Args:\n"
15
+ " base_year (int): The base year for calculating deflation adjustments.\n"
16
+ " source_currency (str, optional): The source currency code. Defaults to 'USA'.\n"
17
+ " target_currency (str, optional): The target currency code. Defaults to 'USA'.\n"
18
+ " countries (list[str] | None, optional): List of country codes to include. If None, returns all. Defaults to None.\n"
19
+ " years (list[int] | range | None, optional): List or range of years to include. If None, returns all. Defaults to None.\n"
20
+ " use_source_codes (bool, optional): Use source-specific entity codes. Defaults to False.\n"
21
+ " to_current (bool, optional): Get deflators for constant-to-current conversion. Defaults to False.\n"
22
+ " include_components (bool, optional): Include price_deflator, exchange_deflator, and exchange_rate columns. Defaults to False.\n"
23
+ " update_deflators (bool, optional): Update the deflator data before retrieval. Defaults to False.\n\n"
24
+ "Returns:\n"
25
+ " pd.DataFrame: DataFrame with columns:\n"
26
+ " - iso_code (or entity_code if use_source_codes=True): Country/entity identifier\n"
27
+ " - year: Year\n"
28
+ " - deflator: The combined deflator value\n"
29
+ " - price_deflator (if include_components=True): The price deflator component\n"
30
+ " - exchange_deflator (if include_components=True): The exchange rate deflator component\n"
31
+ " - exchange_rate (if include_components=True): The exchange rate\n"
32
+ )
33
+
34
+
35
+ def _get_deflator(deflator_source_cls, price_kind):
36
+ """Decorator to create get_deflator wrappers with specific deflator source and price kind."""
37
+
38
+ def decorator(func):
39
+ @wraps(func)
40
+ def wrapper(
41
+ *,
42
+ base_year: int,
43
+ source_currency: str = "USA",
44
+ target_currency: str = "USA",
45
+ countries: list[str] | None = None,
46
+ years: list[int] | range | None = None,
47
+ use_source_codes: bool = False,
48
+ to_current: bool = False,
49
+ include_components: bool = False,
50
+ update_deflators: bool = False,
51
+ ):
52
+ # Validate input parameters
53
+ if not isinstance(base_year, int):
54
+ raise ValueError("The 'base_year' parameter must be an integer.")
55
+
56
+ # Initialize the deflator source
57
+ source = deflator_source_cls(update=update_deflators)
58
+
59
+ # Create a deflator object
60
+ deflator = BaseDeflate(
61
+ base_year=base_year,
62
+ deflator_source=source,
63
+ exchange_source=source,
64
+ source_currency=source_currency,
65
+ target_currency=target_currency,
66
+ price_kind=price_kind,
67
+ use_source_codes=use_source_codes,
68
+ to_current=to_current,
69
+ )
70
+
71
+ # Get the pydeflate data
72
+ data = deflator.pydeflate_data.copy()
73
+
74
+ # Determine the entity column based on use_source_codes
75
+ entity_col = "pydeflate_entity_code" if use_source_codes else "pydeflate_iso3"
76
+
77
+ # Filter by countries if specified
78
+ if countries is not None:
79
+ data = data[data[entity_col].isin(countries)]
80
+
81
+ # Filter by years if specified
82
+ if years is not None:
83
+ if isinstance(years, range):
84
+ years = list(years)
85
+ data = data[data["pydeflate_year"].isin(years)]
86
+
87
+ # Select columns to return
88
+ columns_to_keep = [entity_col, "pydeflate_year", "pydeflate_deflator"]
89
+
90
+ if include_components:
91
+ # Add component columns
92
+ price_col = f"pydeflate_{price_kind}"
93
+ columns_to_keep.extend(
94
+ [price_col, "pydeflate_EXCHANGE_D", "pydeflate_EXCHANGE"]
95
+ )
96
+
97
+ # Keep only the specified columns
98
+ result = data[columns_to_keep].copy()
99
+
100
+ # Rename columns to user-friendly names
101
+ rename_map = {
102
+ entity_col: "entity_code" if use_source_codes else "iso_code",
103
+ "pydeflate_year": "year",
104
+ "pydeflate_deflator": "deflator",
105
+ }
106
+
107
+ if include_components:
108
+ rename_map.update(
109
+ {
110
+ f"pydeflate_{price_kind}": "price_deflator",
111
+ "pydeflate_EXCHANGE_D": "exchange_deflator",
112
+ "pydeflate_EXCHANGE": "exchange_rate",
113
+ }
114
+ )
115
+
116
+ result = result.rename(columns=rename_map)
117
+
118
+ # Reset index
119
+ result = result.reset_index(drop=True)
120
+
121
+ return result
122
+
123
+ wrapper.__doc__ = _generate_get_deflator_docstring(
124
+ deflator_source_cls.__name__, price_kind
125
+ )
126
+ return wrapper
127
+
128
+ return decorator
129
+
130
+
131
+ @_get_deflator(DAC, "NGDP_D")
132
+ def get_oecd_dac_deflators(
133
+ *,
134
+ base_year: int,
135
+ source_currency: str = "USA",
136
+ target_currency: str = "USA",
137
+ countries: list[str] | None = None,
138
+ years: list[int] | range | None = None,
139
+ use_source_codes: bool = False,
140
+ to_current: bool = False,
141
+ include_components: bool = False,
142
+ update_deflators: bool = False,
143
+ ) -> pd.DataFrame: ...
144
+
145
+
146
+ @_get_deflator(WorldBank, "NGDP_D")
147
+ def get_wb_gdp_deflators(
148
+ *,
149
+ base_year: int,
150
+ source_currency: str = "USA",
151
+ target_currency: str = "USA",
152
+ countries: list[str] | None = None,
153
+ years: list[int] | range | None = None,
154
+ use_source_codes: bool = False,
155
+ to_current: bool = False,
156
+ include_components: bool = False,
157
+ update_deflators: bool = False,
158
+ ) -> pd.DataFrame: ...
159
+
160
+
161
+ @_get_deflator(WorldBank, "NGDP_DL")
162
+ def get_wb_gdp_linked_deflators(
163
+ *,
164
+ base_year: int,
165
+ source_currency: str = "USA",
166
+ target_currency: str = "USA",
167
+ countries: list[str] | None = None,
168
+ years: list[int] | range | None = None,
169
+ use_source_codes: bool = False,
170
+ to_current: bool = False,
171
+ include_components: bool = False,
172
+ update_deflators: bool = False,
173
+ ) -> pd.DataFrame: ...
174
+
175
+
176
+ @_get_deflator(WorldBank, "CPI")
177
+ def get_wb_cpi_deflators(
178
+ *,
179
+ base_year: int,
180
+ source_currency: str = "USA",
181
+ target_currency: str = "USA",
182
+ countries: list[str] | None = None,
183
+ years: list[int] | range | None = None,
184
+ use_source_codes: bool = False,
185
+ to_current: bool = False,
186
+ include_components: bool = False,
187
+ update_deflators: bool = False,
188
+ ) -> pd.DataFrame: ...
189
+
190
+
191
+ @_get_deflator(IMF, "NGDP_D")
192
+ def get_imf_gdp_deflators(
193
+ *,
194
+ base_year: int,
195
+ source_currency: str = "USA",
196
+ target_currency: str = "USA",
197
+ countries: list[str] | None = None,
198
+ years: list[int] | range | None = None,
199
+ use_source_codes: bool = False,
200
+ to_current: bool = False,
201
+ include_components: bool = False,
202
+ update_deflators: bool = False,
203
+ ) -> pd.DataFrame: ...
204
+
205
+
206
+ @_get_deflator(IMF, "PCPI")
207
+ def get_imf_cpi_deflators(
208
+ *,
209
+ base_year: int,
210
+ source_currency: str = "USA",
211
+ target_currency: str = "USA",
212
+ countries: list[str] | None = None,
213
+ years: list[int] | range | None = None,
214
+ use_source_codes: bool = False,
215
+ to_current: bool = False,
216
+ include_components: bool = False,
217
+ update_deflators: bool = False,
218
+ ) -> pd.DataFrame: ...
219
+
220
+
221
+ @_get_deflator(IMF, "PCPIE")
222
+ def get_imf_cpi_e_deflators(
223
+ *,
224
+ base_year: int,
225
+ source_currency: str = "USA",
226
+ target_currency: str = "USA",
227
+ countries: list[str] | None = None,
228
+ years: list[int] | range | None = None,
229
+ use_source_codes: bool = False,
230
+ to_current: bool = False,
231
+ include_components: bool = False,
232
+ update_deflators: bool = False,
233
+ ) -> pd.DataFrame: ...
@@ -0,0 +1,207 @@
1
+ from functools import wraps
2
+
3
+ import pandas as pd
4
+
5
+ from pydeflate.core.api import BaseExchange
6
+ from pydeflate.core.source import DAC, IMF, WorldBank, WorldBankPPP
7
+
8
+
9
+ def _generate_get_rates_docstring(source_name: str) -> str:
10
+ """Generate docstring for each get exchange rates function."""
11
+ return (
12
+ f"Get exchange rate data from {source_name} without requiring user data.\n\n"
13
+ f"This function returns a DataFrame containing exchange rates for the specified parameters.\n\n"
14
+ "Args:\n"
15
+ " source_currency (str, optional): The source currency code. Defaults to 'USA'.\n"
16
+ " target_currency (str, optional): The target currency code. Defaults to 'USA'.\n"
17
+ " countries (list[str] | None, optional): List of country codes to include. If None, returns all. Defaults to None.\n"
18
+ " years (list[int] | range | None, optional): List or range of years to include. If None, returns all. Defaults to None.\n"
19
+ " use_source_codes (bool, optional): Use source-specific entity codes. Defaults to False.\n"
20
+ " update_rates (bool, optional): Update the exchange rate data before retrieval. Defaults to False.\n\n"
21
+ "Returns:\n"
22
+ " pd.DataFrame: DataFrame with columns:\n"
23
+ " - iso_code (or entity_code if use_source_codes=True): Country/entity identifier\n"
24
+ " - year: Year\n"
25
+ " - exchange_rate: Exchange rate from source to target currency\n"
26
+ )
27
+
28
+
29
+ def _get_exchange_rates(exchange_source_cls, **fixed_params):
30
+ """Decorator to create get_exchange_rates wrappers with specific source."""
31
+
32
+ def decorator(func):
33
+ @wraps(func)
34
+ def wrapper(
35
+ *,
36
+ source_currency: str = "USA",
37
+ target_currency: str = "USA",
38
+ countries: list[str] | None = None,
39
+ years: list[int] | range | None = None,
40
+ use_source_codes: bool = False,
41
+ update_rates: bool = False,
42
+ ):
43
+ # Apply fixed parameters - no validation needed since these are internally set
44
+ if "target_currency" in fixed_params:
45
+ target_currency = fixed_params["target_currency"]
46
+
47
+ # Initialize the exchange source
48
+ if exchange_source_cls.__name__ == "WorldBankPPP":
49
+ source = exchange_source_cls(
50
+ update=update_rates,
51
+ from_lcu=False if source_currency == "USA" else True,
52
+ )
53
+ source_currency = "LCU" if source_currency == "USA" else source_currency
54
+ else:
55
+ source = exchange_source_cls(update=update_rates)
56
+
57
+ # Create an exchange object
58
+ exchange = BaseExchange(
59
+ exchange_source=source,
60
+ source_currency=source_currency,
61
+ target_currency=target_currency,
62
+ use_source_codes=use_source_codes,
63
+ )
64
+
65
+ # Get the exchange rate data
66
+ data = exchange.pydeflate_data.copy()
67
+
68
+ # Determine the entity column based on use_source_codes
69
+ entity_col = "pydeflate_entity_code" if use_source_codes else "pydeflate_iso3"
70
+
71
+ # Filter by countries if specified
72
+ if countries is not None:
73
+ data = data[data[entity_col].isin(countries)]
74
+
75
+ # Filter by years if specified
76
+ if years is not None:
77
+ if isinstance(years, range):
78
+ years = list(years)
79
+ data = data[data["pydeflate_year"].isin(years)]
80
+
81
+ # Select and rename columns
82
+ result = data[[entity_col, "pydeflate_year", "pydeflate_EXCHANGE"]].copy()
83
+ result = result.rename(
84
+ columns={
85
+ entity_col: "entity_code" if use_source_codes else "iso_code",
86
+ "pydeflate_year": "year",
87
+ "pydeflate_EXCHANGE": "exchange_rate",
88
+ }
89
+ )
90
+
91
+ # Reset index
92
+ result = result.reset_index(drop=True)
93
+
94
+ return result
95
+
96
+ wrapper.__doc__ = _generate_get_rates_docstring(exchange_source_cls.__name__)
97
+ return wrapper
98
+
99
+ return decorator
100
+
101
+
102
+ @_get_exchange_rates(DAC)
103
+ def get_oecd_dac_exchange_rates(
104
+ *,
105
+ source_currency: str = "USA",
106
+ target_currency: str = "USA",
107
+ countries: list[str] | None = None,
108
+ years: list[int] | range | None = None,
109
+ use_source_codes: bool = False,
110
+ update_rates: bool = False,
111
+ ) -> pd.DataFrame: ...
112
+
113
+
114
+ @_get_exchange_rates(WorldBank)
115
+ def get_wb_exchange_rates(
116
+ *,
117
+ source_currency: str = "USA",
118
+ target_currency: str = "USA",
119
+ countries: list[str] | None = None,
120
+ years: list[int] | range | None = None,
121
+ use_source_codes: bool = False,
122
+ update_rates: bool = False,
123
+ ) -> pd.DataFrame: ...
124
+
125
+
126
+ def get_wb_ppp_rates(
127
+ *,
128
+ source_currency: str = "USA",
129
+ countries: list[str] | None = None,
130
+ years: list[int] | range | None = None,
131
+ use_source_codes: bool = False,
132
+ update_rates: bool = False,
133
+ ) -> pd.DataFrame:
134
+ """Get PPP exchange rate data from WorldBankPPP without requiring user data.
135
+
136
+ This function returns a DataFrame containing PPP exchange rates for the specified parameters.
137
+
138
+ Args:
139
+ source_currency (str, optional): The source currency code. Defaults to 'USA'.
140
+ countries (list[str] | None, optional): List of country codes to include. If None, returns all. Defaults to None.
141
+ years (list[int] | range | None, optional): List or range of years to include. If None, returns all. Defaults to None.
142
+ use_source_codes (bool, optional): Use source-specific entity codes. Defaults to False.
143
+ update_rates (bool, optional): Update the exchange rate data before retrieval. Defaults to False.
144
+
145
+ Returns:
146
+ pd.DataFrame: DataFrame with columns:
147
+ - iso_code (or entity_code if use_source_codes=True): Country/entity identifier
148
+ - year: Year
149
+ - exchange_rate: PPP exchange rate
150
+ """
151
+ # Initialize the exchange source
152
+ source = WorldBankPPP(
153
+ update=update_rates,
154
+ from_lcu=False if source_currency == "USA" else True,
155
+ )
156
+ source_currency_internal = "LCU" if source_currency == "USA" else source_currency
157
+
158
+ # Create an exchange object with PPP as target
159
+ exchange = BaseExchange(
160
+ exchange_source=source,
161
+ source_currency=source_currency_internal,
162
+ target_currency="PPP",
163
+ use_source_codes=use_source_codes,
164
+ )
165
+
166
+ # Get the exchange rate data
167
+ data = exchange.pydeflate_data.copy()
168
+
169
+ # Determine the entity column based on use_source_codes
170
+ entity_col = "pydeflate_entity_code" if use_source_codes else "pydeflate_iso3"
171
+
172
+ # Filter by countries if specified
173
+ if countries is not None:
174
+ data = data[data[entity_col].isin(countries)]
175
+
176
+ # Filter by years if specified
177
+ if years is not None:
178
+ if isinstance(years, range):
179
+ years = list(years)
180
+ data = data[data["pydeflate_year"].isin(years)]
181
+
182
+ # Select and rename columns
183
+ result = data[[entity_col, "pydeflate_year", "pydeflate_EXCHANGE"]].copy()
184
+ result = result.rename(
185
+ columns={
186
+ entity_col: "entity_code" if use_source_codes else "iso_code",
187
+ "pydeflate_year": "year",
188
+ "pydeflate_EXCHANGE": "exchange_rate",
189
+ }
190
+ )
191
+
192
+ # Reset index
193
+ result = result.reset_index(drop=True)
194
+
195
+ return result
196
+
197
+
198
+ @_get_exchange_rates(IMF)
199
+ def get_imf_exchange_rates(
200
+ *,
201
+ source_currency: str = "USA",
202
+ target_currency: str = "USA",
203
+ countries: list[str] | None = None,
204
+ years: list[int] | range | None = None,
205
+ use_source_codes: bool = False,
206
+ update_rates: bool = False,
207
+ ) -> pd.DataFrame: ...
File without changes