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.
- {pydeflate-2.1.3 → pydeflate-2.3.0}/LICENSE +1 -1
- pydeflate-2.1.3/README.md → pydeflate-2.3.0/PKG-INFO +257 -0
- pydeflate-2.1.3/PKG-INFO → pydeflate-2.3.0/README.md +231 -23
- pydeflate-2.3.0/pyproject.toml +47 -0
- pydeflate-2.3.0/src/pydeflate/__init__.py +119 -0
- pydeflate-2.3.0/src/pydeflate/cache.py +139 -0
- pydeflate-2.3.0/src/pydeflate/constants.py +121 -0
- pydeflate-2.3.0/src/pydeflate/context.py +211 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/core/api.py +33 -11
- pydeflate-2.3.0/src/pydeflate/core/source.py +144 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/deflate/deflators.py +1 -1
- pydeflate-2.3.0/src/pydeflate/deflate/get_deflators.py +233 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/deflate/legacy_deflate.py +1 -1
- pydeflate-2.3.0/src/pydeflate/exceptions.py +166 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/exchange/exchangers.py +1 -1
- pydeflate-2.3.0/src/pydeflate/exchange/get_rates.py +207 -0
- pydeflate-2.3.0/src/pydeflate/plugins.py +289 -0
- pydeflate-2.3.0/src/pydeflate/protocols.py +168 -0
- pydeflate-2.3.0/src/pydeflate/pydeflate_config.py +114 -0
- pydeflate-2.3.0/src/pydeflate/schemas.py +297 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/common.py +59 -107
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/dac.py +39 -52
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/imf.py +23 -39
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/world_bank.py +44 -117
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/utils.py +14 -9
- pydeflate-2.1.3/pydeflate/__init__.py +0 -47
- pydeflate-2.1.3/pydeflate/core/source.py +0 -63
- pydeflate-2.1.3/pydeflate/pydeflate_config.py +0 -43
- pydeflate-2.1.3/pyproject.toml +0 -29
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/.pydeflate_data/README.md +0 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/core/__init__.py +0 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/core/deflator.py +0 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/core/exchange.py +0 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/deflate/__init__.py +0 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/exchange/__init__.py +0 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/settings/emu.json +0 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/settings/oecd_codes.json +0 -0
- {pydeflate-2.1.3 → pydeflate-2.3.0/src}/pydeflate/sources/__init__.py +0 -0
|
@@ -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
|
[](https://pypi.python.org/pypi/pydeflate)
|
|
4
29
|
[](https://github.com/psf/black)
|
|
5
30
|
[](https://pepy.tech/project/pydeflate)
|
|
31
|
+
[](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
|
[](https://pypi.python.org/pypi/pydeflate)
|
|
27
4
|
[](https://github.com/psf/black)
|
|
28
5
|
[](https://pepy.tech/project/pydeflate)
|
|
6
|
+
[](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"
|