oda-data 2.0.4__tar.gz → 2.0.6__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.
- {oda_data-2.0.4 → oda_data-2.0.6}/PKG-INFO +1 -1
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/api/sources.py +4 -3
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/research/sector_imputations.py +2 -7
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/cache.py +9 -1
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/names/create_mapping.py +32 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/pyproject.toml +1 -1
- {oda_data-2.0.4 → oda_data-2.0.6}/LICENSE +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/README.md +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/.raw_data/README.md +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/api/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/api/constants.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/api/oecd.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/api/representations.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/clean_data/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/clean_data/channels.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/clean_data/common.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/clean_data/crs_channel_mapping.csv +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/clean_data/dtypes.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/clean_data/schema.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/clean_data/validation.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/config.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/common.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/crs/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/crs/common.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/crs/crs_functions.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/crs/crs_indicators.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/crs/oecd.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/crs/one.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac1/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac1/common.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac1/dac1_functions.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac1/dac1_indicators.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac1/oecd.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac1/one.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac2a/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac2a/common.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac2a/dac2a_functions.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac2a/dac2a_indicators.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac2a/oecd.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/dac2a/one.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/indicator.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/research/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/research/eu.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/indicators/research/policy_markers.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/logger.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/crs_flow_types.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/crs_modalities.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/crs_policy_markers.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/crs_purpose.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/crs_type_of_finance.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/dac1_aid_flow_types.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/dac2a_aid_type.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/flow_types.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/indicators.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/key_columns.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/provider_groupings.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/recipient_groupings.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/settings/v1_indicators_mapping.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/compatibility.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/gni.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/groupings.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/names/__init__.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/names/add.py +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/names/crs_names.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/names/dac1_names.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/names/dac2a_names.json +0 -0
- {oda_data-2.0.4 → oda_data-2.0.6}/oda_data/tools/sector_lists.py +0 -0
|
@@ -26,6 +26,7 @@ from oda_data.clean_data.validation import (
|
|
|
26
26
|
check_integers,
|
|
27
27
|
check_strings,
|
|
28
28
|
)
|
|
29
|
+
from oda_data.config import ODAPaths
|
|
29
30
|
from oda_data.logger import logger
|
|
30
31
|
from oda_data.tools.cache import OnDiskCache, generate_param_hash
|
|
31
32
|
|
|
@@ -51,7 +52,7 @@ class Source:
|
|
|
51
52
|
"""
|
|
52
53
|
|
|
53
54
|
memory_cache = TTLCache(maxsize=20, ttl=6000)
|
|
54
|
-
disk_cache = OnDiskCache(
|
|
55
|
+
disk_cache = OnDiskCache(ODAPaths.raw_data, ttl_seconds=86400)
|
|
55
56
|
|
|
56
57
|
def __init__(self):
|
|
57
58
|
self.de_providers = None
|
|
@@ -91,7 +92,7 @@ class DACSource(Source):
|
|
|
91
92
|
"""
|
|
92
93
|
|
|
93
94
|
memory_cache = TTLCache(maxsize=20, ttl=6000)
|
|
94
|
-
disk_cache = OnDiskCache(
|
|
95
|
+
disk_cache = OnDiskCache(ODAPaths.raw_data, ttl_seconds=86400)
|
|
95
96
|
|
|
96
97
|
def __init__(self):
|
|
97
98
|
super().__init__()
|
|
@@ -521,7 +522,7 @@ class AidDataSource(Source):
|
|
|
521
522
|
"""
|
|
522
523
|
|
|
523
524
|
memory_cache = TTLCache(maxsize=20, ttl=6000)
|
|
524
|
-
disk_cache = OnDiskCache(
|
|
525
|
+
disk_cache = OnDiskCache(ODAPaths.raw_data, ttl_seconds=86400)
|
|
525
526
|
|
|
526
527
|
def __init__(self):
|
|
527
528
|
super().__init__()
|
|
@@ -230,7 +230,7 @@ def multilateral_spending_shares_by_channel_and_purpose_smoothed(
|
|
|
230
230
|
)
|
|
231
231
|
)
|
|
232
232
|
|
|
233
|
-
return data.drop(columns=[ODASchema.VALUE])
|
|
233
|
+
return data.drop(columns=[ODASchema.VALUE, ODASchema.PRICES, ODASchema.CURRENCY])
|
|
234
234
|
|
|
235
235
|
|
|
236
236
|
def core_multilateral_contributions_by_provider(
|
|
@@ -313,12 +313,7 @@ def _compute_imputations(
|
|
|
313
313
|
# Merge core contributions with spending shares
|
|
314
314
|
data = multi_spending_shares.merge(
|
|
315
315
|
core_contributions,
|
|
316
|
-
on=[
|
|
317
|
-
ODASchema.CHANNEL_CODE,
|
|
318
|
-
ODASchema.YEAR,
|
|
319
|
-
ODASchema.CURRENCY,
|
|
320
|
-
ODASchema.PRICES,
|
|
321
|
-
],
|
|
316
|
+
on=[ODASchema.CHANNEL_CODE, ODASchema.YEAR],
|
|
322
317
|
how="inner",
|
|
323
318
|
)
|
|
324
319
|
|
|
@@ -2,11 +2,12 @@ import hashlib
|
|
|
2
2
|
import json
|
|
3
3
|
import time
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Optional
|
|
6
6
|
|
|
7
7
|
import pandas as pd
|
|
8
8
|
|
|
9
9
|
from oda_data.logger import logger
|
|
10
|
+
from oda_data.tools.names.create_mapping import snake_to_pascal
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def generate_param_hash(filters: list[tuple]) -> str:
|
|
@@ -48,6 +49,13 @@ class OnDiskCache:
|
|
|
48
49
|
) -> pd.DataFrame | None:
|
|
49
50
|
"""Loads a DataFrame from disk if available and not expired."""
|
|
50
51
|
path = self.get_file_path(dataset_name, param_hash)
|
|
52
|
+
if dataset_name == "MultiSystemData":
|
|
53
|
+
columns = [snake_to_pascal(col) for col in columns] if columns else columns
|
|
54
|
+
filters = (
|
|
55
|
+
[(snake_to_pascal(col), op, val) for col, op, val in filters]
|
|
56
|
+
if filters
|
|
57
|
+
else None
|
|
58
|
+
)
|
|
51
59
|
if not path.exists():
|
|
52
60
|
return None
|
|
53
61
|
if self._is_expired(path):
|
|
@@ -7,6 +7,38 @@ from oda_data.config import ODAPaths
|
|
|
7
7
|
from oda_data.indicators.common import update_mapping_file
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
def snake_to_pascal(name: str, *, keep_single_letter: bool = False) -> str:
|
|
11
|
+
"""
|
|
12
|
+
Convert a snake_case string to PascalCase.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
name : str
|
|
17
|
+
The snake_case identifier to convert.
|
|
18
|
+
keep_single_letter : bool, default False
|
|
19
|
+
If True, preserve the underscore that precedes a 1-letter
|
|
20
|
+
segment (e.g. 'aid_t' → 'Aid_T'). If False, drop it
|
|
21
|
+
('aid_t' → 'AidT').
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
str
|
|
26
|
+
The PascalCase version.
|
|
27
|
+
"""
|
|
28
|
+
parts = name.split("_")
|
|
29
|
+
if not keep_single_letter:
|
|
30
|
+
# Simple path: just capitalise everything and join.
|
|
31
|
+
return "".join(p.capitalize() for p in parts)
|
|
32
|
+
|
|
33
|
+
# Preserve “_” before any single-letter trailing part.
|
|
34
|
+
out: list[str] = []
|
|
35
|
+
for part in parts:
|
|
36
|
+
if len(part) == 1 and out:
|
|
37
|
+
out[-1] = out[-1] + "_" + part.upper()
|
|
38
|
+
else:
|
|
39
|
+
out.append(part.capitalize())
|
|
40
|
+
return "".join(out)
|
|
41
|
+
|
|
10
42
|
def _code_name(df: pd.DataFrame, code_col: str, name_col: str) -> dict:
|
|
11
43
|
"""Return a dictionary mapping code to name."""
|
|
12
44
|
return (
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|