pydeflate 2.1.3__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 (38) hide show
  1. {pydeflate-2.1.3 → pydeflate-2.3.0}/LICENSE +1 -1
  2. pydeflate-2.1.3/README.md → pydeflate-2.3.0/PKG-INFO +257 -0
  3. pydeflate-2.1.3/PKG-INFO → pydeflate-2.3.0/README.md +231 -23
  4. pydeflate-2.3.0/pyproject.toml +47 -0
  5. pydeflate-2.3.0/src/pydeflate/__init__.py +119 -0
  6. pydeflate-2.3.0/src/pydeflate/cache.py +139 -0
  7. pydeflate-2.3.0/src/pydeflate/constants.py +121 -0
  8. pydeflate-2.3.0/src/pydeflate/context.py +211 -0
  9. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/core/api.py +33 -11
  10. pydeflate-2.3.0/src/pydeflate/core/source.py +144 -0
  11. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/deflate/deflators.py +1 -1
  12. pydeflate-2.3.0/src/pydeflate/deflate/get_deflators.py +233 -0
  13. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/deflate/legacy_deflate.py +1 -1
  14. pydeflate-2.3.0/src/pydeflate/exceptions.py +166 -0
  15. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/exchange/exchangers.py +1 -1
  16. pydeflate-2.3.0/src/pydeflate/exchange/get_rates.py +207 -0
  17. pydeflate-2.3.0/src/pydeflate/plugins.py +289 -0
  18. pydeflate-2.3.0/src/pydeflate/protocols.py +168 -0
  19. pydeflate-2.3.0/src/pydeflate/pydeflate_config.py +114 -0
  20. pydeflate-2.3.0/src/pydeflate/schemas.py +297 -0
  21. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/common.py +59 -107
  22. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/dac.py +39 -52
  23. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/imf.py +23 -39
  24. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/world_bank.py +44 -117
  25. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/utils.py +14 -9
  26. pydeflate-2.1.3/pydeflate/__init__.py +0 -47
  27. pydeflate-2.1.3/pydeflate/core/source.py +0 -63
  28. pydeflate-2.1.3/pydeflate/pydeflate_config.py +0 -43
  29. pydeflate-2.1.3/pyproject.toml +0 -29
  30. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/.pydeflate_data/README.md +0 -0
  31. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/core/__init__.py +0 -0
  32. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/core/deflator.py +0 -0
  33. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/core/exchange.py +0 -0
  34. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/deflate/__init__.py +0 -0
  35. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/exchange/__init__.py +0 -0
  36. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/settings/emu.json +0 -0
  37. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/settings/oecd_codes.json +0 -0
  38. {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021-2024, Jorge Rivera
3
+ Copyright (c) 2021-2025, Jorge Rivera
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,8 +1,34 @@
1
+ Metadata-Version: 2.4
2
+ Name: pydeflate
3
+ Version: 2.3.0
4
+ Summary: Package to convert current prices figures to constant prices and vice versa
5
+ Author: Jorge Rivera
6
+ Author-email: Jorge Rivera <Jorge.Rivera@one.org>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Requires-Dist: hdx-python-country>=3.9.8
10
+ Requires-Dist: imf-reader>=1.3.0
11
+ Requires-Dist: oda-reader>=1.2.2
12
+ Requires-Dist: pandas>=2.0
13
+ Requires-Dist: pandera>=0.20.0
14
+ Requires-Dist: pyarrow>=17.0
15
+ Requires-Dist: requests>=2.32.5
16
+ Requires-Dist: wbgapi>=1.0.12
17
+ Requires-Dist: platformdirs>=3.0.0
18
+ Requires-Dist: filelock>=3.15.0
19
+ Maintainer: Jorge Rivera
20
+ Requires-Python: >=3.11
21
+ Project-URL: Homepage, https://github.com/jm-rivera/pydeflate
22
+ Project-URL: Issues, https://github.com/jm-rivera/pydeflate/issues
23
+ Project-URL: Repository, https://github.com/jm-rivera/pydeflate
24
+ Description-Content-Type: text/markdown
25
+
1
26
  # pydeflate
2
27
 
3
28
  [![pypi](https://img.shields.io/pypi/v/pydeflate.svg)](https://pypi.python.org/pypi/pydeflate)
4
29
  [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
5
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/)
6
32
 
7
33
  **pydeflate** is a Python package to:
8
34
  - Convert current price data to constant prices.
@@ -11,6 +37,8 @@
11
37
 
12
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.
13
39
 
40
+ 📚 **[Read the full documentation →](https://jm-rivera.github.io/pydeflate/)**
41
+
14
42
  ## Important Note
15
43
 
16
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.
@@ -33,6 +61,11 @@ When converting to or from constant prices, it takes into account changes in pri
33
61
  - [Currency Conversion](#currency-conversion)
34
62
  - [Example](#example-currency-conversion)
35
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
+
36
69
  - [Example: Using Source-Specific Codes](#example-using-source-specific-codes)
37
70
 
38
71
  - [Data Sources and Method Options](#data-sources-and-method-options)
@@ -157,6 +190,111 @@ df_can = oecd_dac_exchange(
157
190
  )
158
191
  ```
159
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
+
160
298
  ## Example: Using Source-Specific Codes
161
299
 
162
300
  If your data uses source-specific country codes (e.g., DAC codes), set use_source_codes=True and specify the appropriate id_column.
@@ -257,4 +395,123 @@ Pydeflate relies on data from external sources. If there are missing values in t
257
395
 
258
396
  Pydeflate periodically updates its underlying data from the World Bank, IMF, and OECD. If the data on your system is older than 50 days, pydeflate will display a warning upon import.
259
397
 
398
+ ## Advanced Features
399
+
400
+ ### Error Handling
401
+
402
+ Pydeflate v2.1.3+ provides specific exception types for better error handling:
403
+
404
+ ```python
405
+ from pydeflate import imf_gdp_deflate
406
+ from pydeflate.exceptions import NetworkError, ConfigurationError, MissingDataError
407
+
408
+ try:
409
+ result = imf_gdp_deflate(df, base_year=2015, source_currency="USA", target_currency="EUR")
410
+ except NetworkError as e:
411
+ # Handle network failures (retry, fallback to cached data, etc.)
412
+ print(f"Network error: {e}")
413
+ # Implement retry logic
414
+ except ConfigurationError as e:
415
+ # Handle invalid parameters (wrong currency codes, missing columns, etc.)
416
+ print(f"Configuration error: {e}")
417
+ raise
418
+ except MissingDataError as e:
419
+ # Handle missing deflator/exchange data for specific country-year combinations
420
+ print(f"Missing data: {e}")
421
+ # Use alternative source or fill gaps
422
+ ```
423
+
424
+ Available exception types:
425
+ - `PydeflateError`: Base exception for all pydeflate errors
426
+ - `NetworkError`: Network-related failures
427
+ - `ConfigurationError`: Invalid parameters or configuration
428
+ - `DataSourceError`: Issues loading or parsing data from sources
429
+ - `CacheError`: Cache operation failures
430
+ - `MissingDataError`: Required deflator/exchange data unavailable
431
+ - `SchemaValidationError`: Data validation failures
432
+
433
+ ### Custom Data Sources (Plugin System)
434
+
435
+ You can register custom data sources without modifying pydeflate's code:
436
+
437
+ ```python
438
+ from pydeflate.plugins import register_source, list_sources
439
+
440
+ # Define your custom source
441
+ @register_source("my_central_bank")
442
+ class MyCentralBankSource:
443
+ def __init__(self, update: bool = False):
444
+ self.name = "my_central_bank"
445
+ self.data = self.load_my_data(update) # Your data loading logic
446
+ self._idx = ["pydeflate_year", "pydeflate_entity_code", "pydeflate_iso3"]
447
+
448
+ def lcu_usd_exchange(self):
449
+ # Return exchange rate data
450
+ return self.data.filter(self._idx + ["pydeflate_EXCHANGE"])
451
+
452
+ def price_deflator(self, kind="NGDP_D"):
453
+ # Return deflator data
454
+ return self.data.filter(self._idx + [f"pydeflate_{kind}"])
455
+
456
+ def validate(self):
457
+ # Validate data format
458
+ if self.data.empty:
459
+ raise ValueError("No data loaded")
460
+
461
+ # List all available sources
462
+ print(list_sources()) # ['DAC', 'IMF', 'World Bank', 'my_central_bank', ...]
463
+
464
+ # Your custom source is now available for use with pydeflate
465
+ ```
466
+
467
+ ### Advanced Configuration
468
+
469
+ For advanced use cases, you can use context managers to customize pydeflate's behavior:
470
+
471
+ ```python
472
+ from pydeflate.context import pydeflate_session
473
+ import logging
474
+
475
+ # Use a custom cache directory and logging level
476
+ with pydeflate_session(data_dir="/tmp/my_cache", log_level=logging.DEBUG) as ctx:
477
+ result = imf_gdp_deflate(df, base_year=2015, ...)
478
+ # Data is cached in /tmp/my_cache
479
+ # Debug logging is enabled
480
+
481
+ # Or set a default context for your entire application
482
+ from pydeflate.context import PydeflateContext, set_default_context
483
+
484
+ ctx = PydeflateContext.create(
485
+ data_dir="/app/data/pydeflate_cache",
486
+ log_level=logging.INFO
487
+ )
488
+ set_default_context(ctx)
489
+
490
+ # All subsequent pydeflate operations use this configuration
491
+ ```
492
+
493
+ This is useful for:
494
+ - Using different cache directories for different projects
495
+ - Running multiple pydeflate operations in parallel without cache conflicts
496
+ - Customizing logging verbosity
497
+ - Testing with temporary cache directories
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).
260
517
 
@@ -1,31 +1,9 @@
1
- Metadata-Version: 2.3
2
- Name: pydeflate
3
- Version: 2.1.3
4
- Summary: Package to convert current prices figures to constant prices and vice versa
5
- License: MIT
6
- Author: Jorge Rivera
7
- Author-email: jorge.rivera@one.org
8
- Requires-Python: >=3.10, <4.0
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.10
12
- Classifier: Programming Language :: Python :: 3.11
13
- Classifier: Programming Language :: Python :: 3.12
14
- Classifier: Programming Language :: Python :: 3.13
15
- Requires-Dist: hdx-python-country (>=3.8,<4.0.0)
16
- Requires-Dist: imf-reader (>=1.2.0,<2.0.0)
17
- Requires-Dist: oda-reader (>=1.0.5,<2.0.0)
18
- Requires-Dist: pandas (>=2.2.3,<3.0.0)
19
- Requires-Dist: pyarrow (>=14.0)
20
- Requires-Dist: requests (>=2.32.3,<3.0.0)
21
- Requires-Dist: wbgapi (>=1.0.12,<2.0.0)
22
- Description-Content-Type: text/markdown
23
-
24
1
  # pydeflate
25
2
 
26
3
  [![pypi](https://img.shields.io/pypi/v/pydeflate.svg)](https://pypi.python.org/pypi/pydeflate)
27
4
  [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
28
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/)
29
7
 
30
8
  **pydeflate** is a Python package to:
31
9
  - Convert current price data to constant prices.
@@ -34,6 +12,8 @@ Description-Content-Type: text/markdown
34
12
 
35
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.
36
14
 
15
+ 📚 **[Read the full documentation →](https://jm-rivera.github.io/pydeflate/)**
16
+
37
17
  ## Important Note
38
18
 
39
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.
@@ -56,6 +36,11 @@ When converting to or from constant prices, it takes into account changes in pri
56
36
  - [Currency Conversion](#currency-conversion)
57
37
  - [Example](#example-currency-conversion)
58
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
+
59
44
  - [Example: Using Source-Specific Codes](#example-using-source-specific-codes)
60
45
 
61
46
  - [Data Sources and Method Options](#data-sources-and-method-options)
@@ -180,6 +165,111 @@ df_can = oecd_dac_exchange(
180
165
  )
181
166
  ```
182
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
+
183
273
  ## Example: Using Source-Specific Codes
184
274
 
185
275
  If your data uses source-specific country codes (e.g., DAC codes), set use_source_codes=True and specify the appropriate id_column.
@@ -280,5 +370,123 @@ Pydeflate relies on data from external sources. If there are missing values in t
280
370
 
281
371
  Pydeflate periodically updates its underlying data from the World Bank, IMF, and OECD. If the data on your system is older than 50 days, pydeflate will display a warning upon import.
282
372
 
373
+ ## Advanced Features
374
+
375
+ ### Error Handling
376
+
377
+ Pydeflate v2.1.3+ provides specific exception types for better error handling:
378
+
379
+ ```python
380
+ from pydeflate import imf_gdp_deflate
381
+ from pydeflate.exceptions import NetworkError, ConfigurationError, MissingDataError
382
+
383
+ try:
384
+ result = imf_gdp_deflate(df, base_year=2015, source_currency="USA", target_currency="EUR")
385
+ except NetworkError as e:
386
+ # Handle network failures (retry, fallback to cached data, etc.)
387
+ print(f"Network error: {e}")
388
+ # Implement retry logic
389
+ except ConfigurationError as e:
390
+ # Handle invalid parameters (wrong currency codes, missing columns, etc.)
391
+ print(f"Configuration error: {e}")
392
+ raise
393
+ except MissingDataError as e:
394
+ # Handle missing deflator/exchange data for specific country-year combinations
395
+ print(f"Missing data: {e}")
396
+ # Use alternative source or fill gaps
397
+ ```
398
+
399
+ Available exception types:
400
+ - `PydeflateError`: Base exception for all pydeflate errors
401
+ - `NetworkError`: Network-related failures
402
+ - `ConfigurationError`: Invalid parameters or configuration
403
+ - `DataSourceError`: Issues loading or parsing data from sources
404
+ - `CacheError`: Cache operation failures
405
+ - `MissingDataError`: Required deflator/exchange data unavailable
406
+ - `SchemaValidationError`: Data validation failures
407
+
408
+ ### Custom Data Sources (Plugin System)
409
+
410
+ You can register custom data sources without modifying pydeflate's code:
411
+
412
+ ```python
413
+ from pydeflate.plugins import register_source, list_sources
414
+
415
+ # Define your custom source
416
+ @register_source("my_central_bank")
417
+ class MyCentralBankSource:
418
+ def __init__(self, update: bool = False):
419
+ self.name = "my_central_bank"
420
+ self.data = self.load_my_data(update) # Your data loading logic
421
+ self._idx = ["pydeflate_year", "pydeflate_entity_code", "pydeflate_iso3"]
422
+
423
+ def lcu_usd_exchange(self):
424
+ # Return exchange rate data
425
+ return self.data.filter(self._idx + ["pydeflate_EXCHANGE"])
426
+
427
+ def price_deflator(self, kind="NGDP_D"):
428
+ # Return deflator data
429
+ return self.data.filter(self._idx + [f"pydeflate_{kind}"])
430
+
431
+ def validate(self):
432
+ # Validate data format
433
+ if self.data.empty:
434
+ raise ValueError("No data loaded")
435
+
436
+ # List all available sources
437
+ print(list_sources()) # ['DAC', 'IMF', 'World Bank', 'my_central_bank', ...]
438
+
439
+ # Your custom source is now available for use with pydeflate
440
+ ```
441
+
442
+ ### Advanced Configuration
443
+
444
+ For advanced use cases, you can use context managers to customize pydeflate's behavior:
445
+
446
+ ```python
447
+ from pydeflate.context import pydeflate_session
448
+ import logging
449
+
450
+ # Use a custom cache directory and logging level
451
+ with pydeflate_session(data_dir="/tmp/my_cache", log_level=logging.DEBUG) as ctx:
452
+ result = imf_gdp_deflate(df, base_year=2015, ...)
453
+ # Data is cached in /tmp/my_cache
454
+ # Debug logging is enabled
455
+
456
+ # Or set a default context for your entire application
457
+ from pydeflate.context import PydeflateContext, set_default_context
458
+
459
+ ctx = PydeflateContext.create(
460
+ data_dir="/app/data/pydeflate_cache",
461
+ log_level=logging.INFO
462
+ )
463
+ set_default_context(ctx)
464
+
465
+ # All subsequent pydeflate operations use this configuration
466
+ ```
467
+
468
+ This is useful for:
469
+ - Using different cache directories for different projects
470
+ - Running multiple pydeflate operations in parallel without cache conflicts
471
+ - Customizing logging verbosity
472
+ - Testing with temporary cache directories
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
283
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).
284
492
 
@@ -0,0 +1,47 @@
1
+ [project]
2
+ name = "pydeflate"
3
+ version = "2.3.0"
4
+ description = "Package to convert current prices figures to constant prices and vice versa"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ authors = [{ name = "Jorge Rivera", email = "Jorge.Rivera@one.org" }]
8
+ maintainers = [{ name = "Jorge Rivera" }]
9
+ license = "MIT"
10
+ license-files = ["LICENSE*"]
11
+
12
+ dependencies = [
13
+ "hdx-python-country>=3.9.8",
14
+ "imf-reader>=1.3.0",
15
+ "oda-reader>=1.2.2",
16
+ "pandas>=2.0",
17
+ "pandera>=0.20.0",
18
+ "pyarrow>=17.0",
19
+ "requests>=2.32.5",
20
+ "wbgapi>=1.0.12",
21
+ "platformdirs>=3.0.0",
22
+ "filelock>=3.15.0",
23
+ ]
24
+
25
+ [dependency-groups]
26
+ dev = [
27
+ "hypothesis>=6.122.3",
28
+ "pandas-stubs>=2.3.2.250926",
29
+ "pytest>=8.4.2",
30
+ "pytest-cov>=7.0.0",
31
+ "ruff>=0.13.3",
32
+ ]
33
+ docs = [
34
+ "mkdocs-material>=9.5.0",
35
+ "mkdocs-minify-plugin>=0.8.0",
36
+ "mkdocstrings[python]>=0.26.0",
37
+ ]
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/jm-rivera/pydeflate"
41
+ Repository = "https://github.com/jm-rivera/pydeflate"
42
+ Issues = "https://github.com/jm-rivera/pydeflate/issues"
43
+
44
+
45
+ [build-system]
46
+ requires = ["uv_build>=0.8.22,<0.9.0"]
47
+ build-backend = "uv_build"