dcp-tools 1.0.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.
- dcp_tools-1.0.0/LICENSE +21 -0
- dcp_tools-1.0.0/PKG-INFO +168 -0
- dcp_tools-1.0.0/README.md +139 -0
- dcp_tools-1.0.0/pyproject.toml +163 -0
- dcp_tools-1.0.0/pyproject.toml.orig +151 -0
- dcp_tools-1.0.0/src/dcp_tools/__init__.py +15 -0
- dcp_tools-1.0.0/src/dcp_tools/__main__.py +6 -0
- dcp_tools-1.0.0/src/dcp_tools/cli/__init__.py +5 -0
- dcp_tools-1.0.0/src/dcp_tools/cli/common.py +9 -0
- dcp_tools-1.0.0/src/dcp_tools/cli/csv2mcf.py +91 -0
- dcp_tools-1.0.0/src/dcp_tools/cli/ingest.py +35 -0
- dcp_tools-1.0.0/src/dcp_tools/cli/main.py +42 -0
- dcp_tools-1.0.0/src/dcp_tools/cli/pipeline.py +45 -0
- dcp_tools-1.0.0/src/dcp_tools/cli/upload.py +43 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/__init__.py +5 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/config_utils.py +188 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/data_management.py +1696 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/__init__.py +0 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/common.py +249 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/config_file.py +119 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/data_files.py +220 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/mcf.py +263 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/schema_nodes.py +137 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/sources.py +74 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/stat_vars.py +113 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/topics.py +33 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/models/vertical_specs.py +30 -0
- dcp_tools-1.0.0/src/dcp_tools/custom_data/schema_tools.py +297 -0
- dcp_tools-1.0.0/src/dcp_tools/gcp_utilities/__init__.py +22 -0
- dcp_tools-1.0.0/src/dcp_tools/gcp_utilities/clients.py +23 -0
- dcp_tools-1.0.0/src/dcp_tools/gcp_utilities/ingestion.py +36 -0
- dcp_tools-1.0.0/src/dcp_tools/gcp_utilities/pipeline.py +45 -0
- dcp_tools-1.0.0/src/dcp_tools/gcp_utilities/settings.py +106 -0
- dcp_tools-1.0.0/src/dcp_tools/gcp_utilities/storage.py +412 -0
- dcp_tools-1.0.0/src/dcp_tools/logger.py +25 -0
- dcp_tools-1.0.0/src/dcp_tools/py.typed +0 -0
dcp_tools-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ONE Campaign
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
dcp_tools-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dcp-tools
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Tools to work with the Data Commons Platform.
|
|
5
|
+
Keywords: data-commons,datacommons,dcp,etl,statistics
|
|
6
|
+
Author: ONE Campaign, Luca Picci, Jorge Rivera
|
|
7
|
+
Author-email: Luca Picci <lpicci96@gmail.com>, Jorge Rivera <jorge.rivera@one.org>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Dist: pydantic>=2.11.3,<3.0.0
|
|
19
|
+
Requires-Dist: pandas>=2.2.3,<4.0.0
|
|
20
|
+
Requires-Dist: pydantic-settings>=2.9.1,<3.0.0
|
|
21
|
+
Requires-Dist: google-cloud-storage>=3.1.0,<4.0.0
|
|
22
|
+
Requires-Dist: datacommons-admin>=1.1.1
|
|
23
|
+
Requires-Python: >=3.13
|
|
24
|
+
Project-URL: homepage, https://docs.one.org/tools/dcp-tools/
|
|
25
|
+
Project-URL: documentation, https://docs.one.org/tools/dcp-tools/
|
|
26
|
+
Project-URL: repository, https://github.com/ONEcampaign/dcp-tools
|
|
27
|
+
Project-URL: issues, https://github.com/ONEcampaign/dcp-tools/issues
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# dcp-tools
|
|
31
|
+
|
|
32
|
+
__Manage and load data to Data Commons Platform instances__
|
|
33
|
+
|
|
34
|
+
[](https://pypi.org/project/dcp-tools/)
|
|
35
|
+
[](https://pypi.org/project/dcp-tools/)
|
|
36
|
+
[](https://docs.one.org/tools/dcp-tools/)
|
|
37
|
+
[](https://github.com/astral-sh/ruff)
|
|
38
|
+
|
|
39
|
+
A [Data Commons Platform](https://docs.datacommons.org/custom_dc/custom_data.html) instance takes
|
|
40
|
+
your data as CSVs in a fixed variable-per-row shape, plus a `config.json` that maps each CSV's
|
|
41
|
+
columns onto the Data Commons schema. If you're defining your own statistical variables,
|
|
42
|
+
entities, or properties rather than reusing existing ones, you also need MCF (Meta Content
|
|
43
|
+
Framework) files describing them. `dcp-tools` builds and validates that bundle in Python (or from
|
|
44
|
+
the CLI) and uploads it to Cloud Storage to trigger the platform's ingestion workflow.
|
|
45
|
+
|
|
46
|
+
This package was published as `bblocks-datacommons-tools` until version 0.1.1, and imported as
|
|
47
|
+
`bblocks.datacommons_tools`. Installing the old distribution now pulls in `dcp-tools` and
|
|
48
|
+
redirects those imports with a `DeprecationWarning`, so existing code keeps working. Update
|
|
49
|
+
imports to `dcp_tools` when convenient.
|
|
50
|
+
|
|
51
|
+
## Install
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install dcp-tools
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or from GitHub:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install git+https://github.com/ONEcampaign/dcp-tools
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Quickstart
|
|
64
|
+
|
|
65
|
+
This builds a config and MCF for a source, a provenance, one input file, and one statistical
|
|
66
|
+
variable, then exports the bundle to disk.
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from pathlib import Path
|
|
70
|
+
|
|
71
|
+
import pandas as pd
|
|
72
|
+
from dcp_tools import CustomDataManager
|
|
73
|
+
|
|
74
|
+
manager = CustomDataManager()
|
|
75
|
+
manager.add_source(dcid="ONEData", url="https://data.one.org")
|
|
76
|
+
manager.add_provenance(
|
|
77
|
+
dcid="ONEClimateFinance",
|
|
78
|
+
url="https://datacommons.one.org/data/climate-finance-files",
|
|
79
|
+
source="ONEData",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
data = pd.DataFrame({
|
|
83
|
+
"country": ["Kenya", "Kenya", "Vietnam"],
|
|
84
|
+
"year": [2022, 2023, 2023],
|
|
85
|
+
"variable": ["climateFinanceProvidedCommitments"] * 3,
|
|
86
|
+
"value": [12.4, 15.1, 8.7],
|
|
87
|
+
})
|
|
88
|
+
manager.add_input_file(
|
|
89
|
+
file_name="climate_finance/one_cf_provider_commitments.csv",
|
|
90
|
+
provenance="ONEClimateFinance",
|
|
91
|
+
data=data,
|
|
92
|
+
column_mappings={
|
|
93
|
+
"observationAbout": "country",
|
|
94
|
+
"date": "year",
|
|
95
|
+
"variable": "variable",
|
|
96
|
+
"value": "value",
|
|
97
|
+
},
|
|
98
|
+
observation_properties={"unit": "USDollar"},
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
manager.add_variable_to_mcf(
|
|
102
|
+
dcid="climateFinanceProvidedCommitments",
|
|
103
|
+
name="Climate finance commitments (bilateral)",
|
|
104
|
+
description="Funding committed for climate adaptation and mitigation projects",
|
|
105
|
+
stat_type="dcid:measuredValue",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
manager.add_mcf_file("*.mcf", provenance="ONEClimateFinance")
|
|
109
|
+
|
|
110
|
+
out_dir = Path("export/climate_finance")
|
|
111
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
112
|
+
manager.export_all(out_dir)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`export_all` writes `config.json`, the CSV, and both MCF files under `out_dir`. Since we
|
|
116
|
+
never called `set_import_name`, `config.json` defaults `importName` to the export directory's
|
|
117
|
+
name, and column mappings and the provenance name are resolved to full dcids:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"importName": "climate_finance",
|
|
122
|
+
"inputFiles": [
|
|
123
|
+
{
|
|
124
|
+
"filename": "climate_finance/one_cf_provider_commitments.csv",
|
|
125
|
+
"provenance": "dcid:provenance/ONEClimateFinance",
|
|
126
|
+
"columnMappings": {
|
|
127
|
+
"dcid:variableMeasured": "variable",
|
|
128
|
+
"dcid:observationDate": "year",
|
|
129
|
+
"dcid:value": "value",
|
|
130
|
+
"dcid:observationAbout": "country"
|
|
131
|
+
},
|
|
132
|
+
"observationProperties": {"unit": "USDollar"},
|
|
133
|
+
"format": "variablePerRow"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"pattern": "*.mcf",
|
|
137
|
+
"provenance": "dcid:provenance/ONEClimateFinance"
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Loading it
|
|
144
|
+
|
|
145
|
+
Once you have a bundle on disk, `dcp_tools.gcp_utilities` uploads it and triggers ingestion:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from dcp_tools.gcp_utilities import (
|
|
149
|
+
get_kg_settings,
|
|
150
|
+
run_ingestion_workflow,
|
|
151
|
+
upload_to_cloud_storage,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
settings = get_kg_settings(source="env", env_file="customDC.env")
|
|
155
|
+
upload_to_cloud_storage(settings=settings, directory="export/climate_finance")
|
|
156
|
+
run_ingestion_workflow(settings=settings)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`run_ingestion_workflow` triggers the DCP (Data Commons Platform) ingestion workflow, which
|
|
160
|
+
ingests the new data and serves it. There's no separate redeploy step to run. See the
|
|
161
|
+
[loading-data docs](https://docs.one.org/tools/dcp-tools/loading-data/) for the
|
|
162
|
+
full settings reference, and the `dcp-tools` CLI (`upload`, `ingest`, `pipeline`), which wraps
|
|
163
|
+
this same flow.
|
|
164
|
+
|
|
165
|
+
## Contributing
|
|
166
|
+
|
|
167
|
+
Contributions are welcome! See [CONTRIBUTING](https://github.com/ONEcampaign/dcp-tools/blob/main/CONTRIBUTING.MD)
|
|
168
|
+
for how to get started, report bugs, and submit changes.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# dcp-tools
|
|
2
|
+
|
|
3
|
+
__Manage and load data to Data Commons Platform instances__
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/dcp-tools/)
|
|
6
|
+
[](https://pypi.org/project/dcp-tools/)
|
|
7
|
+
[](https://docs.one.org/tools/dcp-tools/)
|
|
8
|
+
[](https://github.com/astral-sh/ruff)
|
|
9
|
+
|
|
10
|
+
A [Data Commons Platform](https://docs.datacommons.org/custom_dc/custom_data.html) instance takes
|
|
11
|
+
your data as CSVs in a fixed variable-per-row shape, plus a `config.json` that maps each CSV's
|
|
12
|
+
columns onto the Data Commons schema. If you're defining your own statistical variables,
|
|
13
|
+
entities, or properties rather than reusing existing ones, you also need MCF (Meta Content
|
|
14
|
+
Framework) files describing them. `dcp-tools` builds and validates that bundle in Python (or from
|
|
15
|
+
the CLI) and uploads it to Cloud Storage to trigger the platform's ingestion workflow.
|
|
16
|
+
|
|
17
|
+
This package was published as `bblocks-datacommons-tools` until version 0.1.1, and imported as
|
|
18
|
+
`bblocks.datacommons_tools`. Installing the old distribution now pulls in `dcp-tools` and
|
|
19
|
+
redirects those imports with a `DeprecationWarning`, so existing code keeps working. Update
|
|
20
|
+
imports to `dcp_tools` when convenient.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install dcp-tools
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or from GitHub:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install git+https://github.com/ONEcampaign/dcp-tools
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quickstart
|
|
35
|
+
|
|
36
|
+
This builds a config and MCF for a source, a provenance, one input file, and one statistical
|
|
37
|
+
variable, then exports the bundle to disk.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
|
|
42
|
+
import pandas as pd
|
|
43
|
+
from dcp_tools import CustomDataManager
|
|
44
|
+
|
|
45
|
+
manager = CustomDataManager()
|
|
46
|
+
manager.add_source(dcid="ONEData", url="https://data.one.org")
|
|
47
|
+
manager.add_provenance(
|
|
48
|
+
dcid="ONEClimateFinance",
|
|
49
|
+
url="https://datacommons.one.org/data/climate-finance-files",
|
|
50
|
+
source="ONEData",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
data = pd.DataFrame({
|
|
54
|
+
"country": ["Kenya", "Kenya", "Vietnam"],
|
|
55
|
+
"year": [2022, 2023, 2023],
|
|
56
|
+
"variable": ["climateFinanceProvidedCommitments"] * 3,
|
|
57
|
+
"value": [12.4, 15.1, 8.7],
|
|
58
|
+
})
|
|
59
|
+
manager.add_input_file(
|
|
60
|
+
file_name="climate_finance/one_cf_provider_commitments.csv",
|
|
61
|
+
provenance="ONEClimateFinance",
|
|
62
|
+
data=data,
|
|
63
|
+
column_mappings={
|
|
64
|
+
"observationAbout": "country",
|
|
65
|
+
"date": "year",
|
|
66
|
+
"variable": "variable",
|
|
67
|
+
"value": "value",
|
|
68
|
+
},
|
|
69
|
+
observation_properties={"unit": "USDollar"},
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
manager.add_variable_to_mcf(
|
|
73
|
+
dcid="climateFinanceProvidedCommitments",
|
|
74
|
+
name="Climate finance commitments (bilateral)",
|
|
75
|
+
description="Funding committed for climate adaptation and mitigation projects",
|
|
76
|
+
stat_type="dcid:measuredValue",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
manager.add_mcf_file("*.mcf", provenance="ONEClimateFinance")
|
|
80
|
+
|
|
81
|
+
out_dir = Path("export/climate_finance")
|
|
82
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
83
|
+
manager.export_all(out_dir)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`export_all` writes `config.json`, the CSV, and both MCF files under `out_dir`. Since we
|
|
87
|
+
never called `set_import_name`, `config.json` defaults `importName` to the export directory's
|
|
88
|
+
name, and column mappings and the provenance name are resolved to full dcids:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"importName": "climate_finance",
|
|
93
|
+
"inputFiles": [
|
|
94
|
+
{
|
|
95
|
+
"filename": "climate_finance/one_cf_provider_commitments.csv",
|
|
96
|
+
"provenance": "dcid:provenance/ONEClimateFinance",
|
|
97
|
+
"columnMappings": {
|
|
98
|
+
"dcid:variableMeasured": "variable",
|
|
99
|
+
"dcid:observationDate": "year",
|
|
100
|
+
"dcid:value": "value",
|
|
101
|
+
"dcid:observationAbout": "country"
|
|
102
|
+
},
|
|
103
|
+
"observationProperties": {"unit": "USDollar"},
|
|
104
|
+
"format": "variablePerRow"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"pattern": "*.mcf",
|
|
108
|
+
"provenance": "dcid:provenance/ONEClimateFinance"
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Loading it
|
|
115
|
+
|
|
116
|
+
Once you have a bundle on disk, `dcp_tools.gcp_utilities` uploads it and triggers ingestion:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from dcp_tools.gcp_utilities import (
|
|
120
|
+
get_kg_settings,
|
|
121
|
+
run_ingestion_workflow,
|
|
122
|
+
upload_to_cloud_storage,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
settings = get_kg_settings(source="env", env_file="customDC.env")
|
|
126
|
+
upload_to_cloud_storage(settings=settings, directory="export/climate_finance")
|
|
127
|
+
run_ingestion_workflow(settings=settings)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`run_ingestion_workflow` triggers the DCP (Data Commons Platform) ingestion workflow, which
|
|
131
|
+
ingests the new data and serves it. There's no separate redeploy step to run. See the
|
|
132
|
+
[loading-data docs](https://docs.one.org/tools/dcp-tools/loading-data/) for the
|
|
133
|
+
full settings reference, and the `dcp-tools` CLI (`upload`, `ingest`, `pipeline`), which wraps
|
|
134
|
+
this same flow.
|
|
135
|
+
|
|
136
|
+
## Contributing
|
|
137
|
+
|
|
138
|
+
Contributions are welcome! See [CONTRIBUTING](https://github.com/ONEcampaign/dcp-tools/blob/main/CONTRIBUTING.MD)
|
|
139
|
+
for how to get started, report bugs, and submit changes.
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "dcp-tools"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Tools to work with the Data Commons Platform."
|
|
5
|
+
license = "MIT"
|
|
6
|
+
license-files = ["LICENSE"]
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
requires-python = ">=3.13"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"pydantic>=2.11.3,<3.0.0",
|
|
11
|
+
"pandas>=2.2.3,<4.0.0",
|
|
12
|
+
"pydantic-settings>=2.9.1,<3.0.0",
|
|
13
|
+
"google-cloud-storage>=3.1.0,<4.0.0",
|
|
14
|
+
"datacommons-admin>=1.1.1",
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"data-commons",
|
|
18
|
+
"datacommons",
|
|
19
|
+
"dcp",
|
|
20
|
+
"etl",
|
|
21
|
+
"statistics",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 5 - Production/Stable",
|
|
25
|
+
"Intended Audience :: Developers",
|
|
26
|
+
"Operating System :: OS Independent",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Programming Language :: Python :: 3.14",
|
|
29
|
+
"Topic :: Scientific/Engineering :: Information Analysis",
|
|
30
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
31
|
+
"Typing :: Typed",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[[project.authors]]
|
|
35
|
+
name = "ONE Campaign"
|
|
36
|
+
|
|
37
|
+
[[project.authors]]
|
|
38
|
+
name = "Luca Picci"
|
|
39
|
+
email = "lpicci96@gmail.com"
|
|
40
|
+
|
|
41
|
+
[[project.authors]]
|
|
42
|
+
name = "Jorge Rivera"
|
|
43
|
+
email = "jorge.rivera@one.org"
|
|
44
|
+
|
|
45
|
+
[project.scripts]
|
|
46
|
+
dcp-tools = "dcp_tools.cli:main"
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
homepage = "https://docs.one.org/tools/dcp-tools/"
|
|
50
|
+
documentation = "https://docs.one.org/tools/dcp-tools/"
|
|
51
|
+
repository = "https://github.com/ONEcampaign/dcp-tools"
|
|
52
|
+
issues = "https://github.com/ONEcampaign/dcp-tools/issues"
|
|
53
|
+
|
|
54
|
+
[dependency-groups]
|
|
55
|
+
dev = [
|
|
56
|
+
"pytest>=8.0.0",
|
|
57
|
+
"pytest-cov>=4.1.0",
|
|
58
|
+
"ty>=0.0.33",
|
|
59
|
+
"ruff>=0.8.0",
|
|
60
|
+
"pre-commit>=3.0.0",
|
|
61
|
+
"mkdocs-material>=9.6.14,<10.0.0",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
[build-system]
|
|
65
|
+
requires = ["uv_build>=0.11.8,<0.12"]
|
|
66
|
+
build-backend = "uv_build"
|
|
67
|
+
|
|
68
|
+
[tool.ruff]
|
|
69
|
+
line-length = 88
|
|
70
|
+
target-version = "py313"
|
|
71
|
+
extend-include = ["*.ipynb"]
|
|
72
|
+
exclude = [
|
|
73
|
+
".git",
|
|
74
|
+
".venv",
|
|
75
|
+
"venv",
|
|
76
|
+
"__pycache__",
|
|
77
|
+
"build",
|
|
78
|
+
"dist",
|
|
79
|
+
"*.egg-info",
|
|
80
|
+
".pytest_cache",
|
|
81
|
+
"htmlcov",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
[tool.ruff.lint]
|
|
85
|
+
select = [
|
|
86
|
+
"E",
|
|
87
|
+
"W",
|
|
88
|
+
"F",
|
|
89
|
+
"I",
|
|
90
|
+
"UP",
|
|
91
|
+
"B",
|
|
92
|
+
"C4",
|
|
93
|
+
"SIM",
|
|
94
|
+
"PL",
|
|
95
|
+
"RUF",
|
|
96
|
+
"ERA",
|
|
97
|
+
"PERF",
|
|
98
|
+
"ANN",
|
|
99
|
+
]
|
|
100
|
+
ignore = [
|
|
101
|
+
"E501",
|
|
102
|
+
"PLR0913",
|
|
103
|
+
"PLR0912",
|
|
104
|
+
"PLR0914",
|
|
105
|
+
"PLR0915",
|
|
106
|
+
"PLR2004",
|
|
107
|
+
"ANN401",
|
|
108
|
+
]
|
|
109
|
+
fixable = ["ALL"]
|
|
110
|
+
unfixable = []
|
|
111
|
+
|
|
112
|
+
[tool.ruff.lint.per-file-ignores]
|
|
113
|
+
"tests/**/*.py" = [
|
|
114
|
+
"ANN",
|
|
115
|
+
"PLR2004",
|
|
116
|
+
]
|
|
117
|
+
"**/*.ipynb" = [
|
|
118
|
+
"ANN",
|
|
119
|
+
"F401",
|
|
120
|
+
"F811",
|
|
121
|
+
"E402",
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
[tool.ruff.lint.pydocstyle]
|
|
125
|
+
convention = "google"
|
|
126
|
+
|
|
127
|
+
[tool.ruff.format]
|
|
128
|
+
quote-style = "double"
|
|
129
|
+
indent-style = "space"
|
|
130
|
+
skip-magic-trailing-comma = false
|
|
131
|
+
line-ending = "auto"
|
|
132
|
+
|
|
133
|
+
[tool.ty.environment]
|
|
134
|
+
python-version = "3.13"
|
|
135
|
+
|
|
136
|
+
[tool.ty.src]
|
|
137
|
+
include = ["src/dcp_tools"]
|
|
138
|
+
|
|
139
|
+
[tool.pytest.ini_options]
|
|
140
|
+
testpaths = ["tests"]
|
|
141
|
+
python_files = ["test_*.py"]
|
|
142
|
+
addopts = "-v --cov=src/dcp_tools --cov-report=term"
|
|
143
|
+
|
|
144
|
+
[tool.coverage.run]
|
|
145
|
+
source = ["src"]
|
|
146
|
+
branch = true
|
|
147
|
+
omit = [
|
|
148
|
+
"*/tests/*",
|
|
149
|
+
"*/__pycache__/*",
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
[tool.coverage.report]
|
|
153
|
+
exclude_lines = [
|
|
154
|
+
"pragma: no cover",
|
|
155
|
+
"def __repr__",
|
|
156
|
+
"def __str__",
|
|
157
|
+
"raise AssertionError",
|
|
158
|
+
"raise NotImplementedError",
|
|
159
|
+
"if __name__ == .__main__.:",
|
|
160
|
+
"if TYPE_CHECKING:",
|
|
161
|
+
]
|
|
162
|
+
show_missing = true
|
|
163
|
+
precision = 2
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "dcp-tools"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Tools to work with the Data Commons Platform."
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "ONE Campaign" },
|
|
7
|
+
{ name = "Luca Picci", email = "lpicci96@gmail.com" },
|
|
8
|
+
{ name = "Jorge Rivera", email = "jorge.rivera@one.org" },
|
|
9
|
+
]
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.13"
|
|
14
|
+
dependencies = [
|
|
15
|
+
"pydantic>=2.11.3,<3.0.0",
|
|
16
|
+
"pandas>=2.2.3,<4.0.0",
|
|
17
|
+
"pydantic-settings>=2.9.1,<3.0.0",
|
|
18
|
+
"google-cloud-storage>=3.1.0,<4.0.0",
|
|
19
|
+
"datacommons-admin>=1.1.1",
|
|
20
|
+
]
|
|
21
|
+
keywords = ["data-commons", "datacommons", "dcp", "etl", "statistics"]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 5 - Production/Stable",
|
|
24
|
+
"Intended Audience :: Developers",
|
|
25
|
+
"Operating System :: OS Independent",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Programming Language :: Python :: 3.14",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Information Analysis",
|
|
29
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
30
|
+
"Typing :: Typed",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
dcp-tools = "dcp_tools.cli:main"
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
homepage = "https://docs.one.org/tools/dcp-tools/"
|
|
38
|
+
documentation = "https://docs.one.org/tools/dcp-tools/"
|
|
39
|
+
repository = "https://github.com/ONEcampaign/dcp-tools"
|
|
40
|
+
issues = "https://github.com/ONEcampaign/dcp-tools/issues"
|
|
41
|
+
|
|
42
|
+
[dependency-groups]
|
|
43
|
+
dev = [
|
|
44
|
+
"pytest>=8.0.0",
|
|
45
|
+
"pytest-cov>=4.1.0",
|
|
46
|
+
"ty>=0.0.33",
|
|
47
|
+
"ruff>=0.8.0",
|
|
48
|
+
"pre-commit>=3.0.0",
|
|
49
|
+
"mkdocs-material>=9.6.14,<10.0.0",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[build-system]
|
|
53
|
+
requires = ["uv_build>=0.11.8,<0.12"]
|
|
54
|
+
build-backend = "uv_build"
|
|
55
|
+
|
|
56
|
+
[tool.ruff]
|
|
57
|
+
line-length = 88
|
|
58
|
+
target-version = "py313"
|
|
59
|
+
extend-include = ["*.ipynb"]
|
|
60
|
+
|
|
61
|
+
exclude = [
|
|
62
|
+
".git",
|
|
63
|
+
".venv",
|
|
64
|
+
"venv",
|
|
65
|
+
"__pycache__",
|
|
66
|
+
"build",
|
|
67
|
+
"dist",
|
|
68
|
+
"*.egg-info",
|
|
69
|
+
".pytest_cache",
|
|
70
|
+
"htmlcov",
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
[tool.ruff.lint]
|
|
74
|
+
# "N" (pep8-naming) is intentionally omitted: the public API mirrors the Data
|
|
75
|
+
# Commons config.json schema, which is camelCase (e.g. ``importName``,
|
|
76
|
+
# ``set_includeInputSubdirs``). Those names are a serialization contract, not a
|
|
77
|
+
# style choice, so the naming rules would fight the domain.
|
|
78
|
+
select = [
|
|
79
|
+
"E", "W", "F", # pycodestyle, pyflakes
|
|
80
|
+
"I", # isort
|
|
81
|
+
"UP", # pyupgrade
|
|
82
|
+
"B", # bugbear
|
|
83
|
+
"C4", # comprehensions
|
|
84
|
+
"SIM", # simplify
|
|
85
|
+
"PL", # pylint
|
|
86
|
+
"RUF", # ruff-specific
|
|
87
|
+
"ERA", # eradicate (commented-out code)
|
|
88
|
+
"PERF", # perflint
|
|
89
|
+
"ANN", # flake8-annotations (require type hints on public APIs)
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
ignore = [
|
|
93
|
+
"E501", # Line length (formatter handles)
|
|
94
|
+
"PLR0913", # Too many arguments
|
|
95
|
+
"PLR0912", # Too many branches
|
|
96
|
+
"PLR0914", # Too many locals
|
|
97
|
+
"PLR0915", # Too many statements
|
|
98
|
+
"PLR2004", # Magic values
|
|
99
|
+
"ANN401", # Allow `Any` in typed signatures
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
# Allow autofix for all enabled rules
|
|
103
|
+
fixable = ["ALL"]
|
|
104
|
+
unfixable = []
|
|
105
|
+
|
|
106
|
+
[tool.ruff.lint.per-file-ignores]
|
|
107
|
+
# Tests don't need annotations or pylint-complexity gates.
|
|
108
|
+
"tests/**/*.py" = ["ANN", "PLR2004"]
|
|
109
|
+
# Notebooks: don't require annotations; allow REPL-style patterns.
|
|
110
|
+
"**/*.ipynb" = ["ANN", "F401", "F811", "E402"]
|
|
111
|
+
|
|
112
|
+
[tool.ruff.lint.pydocstyle]
|
|
113
|
+
convention = "google"
|
|
114
|
+
|
|
115
|
+
[tool.ruff.format]
|
|
116
|
+
quote-style = "double"
|
|
117
|
+
indent-style = "space"
|
|
118
|
+
skip-magic-trailing-comma = false
|
|
119
|
+
line-ending = "auto"
|
|
120
|
+
|
|
121
|
+
[tool.ty.environment]
|
|
122
|
+
python-version = "3.13"
|
|
123
|
+
|
|
124
|
+
[tool.ty.src]
|
|
125
|
+
include = ["src/dcp_tools"]
|
|
126
|
+
|
|
127
|
+
[tool.pytest.ini_options]
|
|
128
|
+
testpaths = ["tests"]
|
|
129
|
+
python_files = ["test_*.py"]
|
|
130
|
+
addopts = "-v --cov=src/dcp_tools --cov-report=term"
|
|
131
|
+
|
|
132
|
+
[tool.coverage.run]
|
|
133
|
+
source = ["src"]
|
|
134
|
+
branch = true
|
|
135
|
+
omit = [
|
|
136
|
+
"*/tests/*",
|
|
137
|
+
"*/__pycache__/*",
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
[tool.coverage.report]
|
|
141
|
+
exclude_lines = [
|
|
142
|
+
"pragma: no cover",
|
|
143
|
+
"def __repr__",
|
|
144
|
+
"def __str__",
|
|
145
|
+
"raise AssertionError",
|
|
146
|
+
"raise NotImplementedError",
|
|
147
|
+
"if __name__ == .__main__.:",
|
|
148
|
+
"if TYPE_CHECKING:",
|
|
149
|
+
]
|
|
150
|
+
show_missing = true
|
|
151
|
+
precision = 2
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from importlib.metadata import version
|
|
2
|
+
|
|
3
|
+
from .custom_data.config_utils import merge_configs_from_directory
|
|
4
|
+
from .custom_data.data_management import CustomDataManager
|
|
5
|
+
from .custom_data.schema_tools import csv_metadata_to_mcf_file, csv_metadata_to_nodes
|
|
6
|
+
|
|
7
|
+
__version__ = version("dcp-tools")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"CustomDataManager",
|
|
12
|
+
"csv_metadata_to_mcf_file",
|
|
13
|
+
"csv_metadata_to_nodes",
|
|
14
|
+
"merge_configs_from_directory",
|
|
15
|
+
]
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
from dcp_tools.gcp_utilities import KGSettings, get_kg_settings
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def load_settings_from_args(args: argparse.Namespace) -> KGSettings:
|
|
7
|
+
if args.settings_file:
|
|
8
|
+
return get_kg_settings(source="json", file=args.settings_file)
|
|
9
|
+
return get_kg_settings(env_file=args.env_file)
|