owid-datautils 0.6.1__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.
- owid_datautils-0.6.1/.bumpversion.cfg +12 -0
- owid_datautils-0.6.1/.codecov.yml +13 -0
- owid_datautils-0.6.1/.github/workflows/python-package.yml +52 -0
- owid_datautils-0.6.1/.gitignore +141 -0
- owid_datautils-0.6.1/.pre-commit-config.yaml +15 -0
- owid_datautils-0.6.1/.readthedocs.yaml +23 -0
- owid_datautils-0.6.1/LICENSE +21 -0
- owid_datautils-0.6.1/Makefile +8 -0
- owid_datautils-0.6.1/PKG-INFO +20 -0
- owid_datautils-0.6.1/README.md +85 -0
- owid_datautils-0.6.1/docs/Makefile +20 -0
- owid_datautils-0.6.1/docs/_static/favicon.ico +0 -0
- owid_datautils-0.6.1/docs/_static/owid.png +0 -0
- owid_datautils-0.6.1/docs/apidoc-templates/module.rst_t +8 -0
- owid_datautils-0.6.1/docs/apidoc-templates/package.rst_t +52 -0
- owid_datautils-0.6.1/docs/apidoc-templates/toc.rst_t +7 -0
- owid_datautils-0.6.1/docs/conf.py +90 -0
- owid_datautils-0.6.1/docs/index.rst +12 -0
- owid_datautils-0.6.1/docs/make.bat +35 -0
- owid_datautils-0.6.1/owid/datautils/__init__.py +3 -0
- owid_datautils-0.6.1/owid/datautils/checks.py +1 -0
- owid_datautils-0.6.1/owid/datautils/common.py +44 -0
- owid_datautils-0.6.1/owid/datautils/dataframes.py +739 -0
- owid_datautils-0.6.1/owid/datautils/decorators.py +91 -0
- owid_datautils-0.6.1/owid/datautils/format/__init__.py +7 -0
- owid_datautils-0.6.1/owid/datautils/format/numbers.py +304 -0
- owid_datautils-0.6.1/owid/datautils/google/__init__.py +7 -0
- owid_datautils-0.6.1/owid/datautils/google/api.py +136 -0
- owid_datautils-0.6.1/owid/datautils/google/config.py +117 -0
- owid_datautils-0.6.1/owid/datautils/google/sheets.py +134 -0
- owid_datautils-0.6.1/owid/datautils/io/__init__.py +14 -0
- owid_datautils-0.6.1/owid/datautils/io/archive.py +84 -0
- owid_datautils-0.6.1/owid/datautils/io/df.py +163 -0
- owid_datautils-0.6.1/owid/datautils/io/json.py +78 -0
- owid_datautils-0.6.1/owid/datautils/ui.py +32 -0
- owid_datautils-0.6.1/owid/datautils/web.py +106 -0
- owid_datautils-0.6.1/pyproject.toml +57 -0
- owid_datautils-0.6.1/tests/__init__.py +0 -0
- owid_datautils-0.6.1/tests/format/__init__.py +3 -0
- owid_datautils-0.6.1/tests/format/test_numbers.py +221 -0
- owid_datautils-0.6.1/tests/google/__init__.py +0 -0
- owid_datautils-0.6.1/tests/google/test_api.py +29 -0
- owid_datautils-0.6.1/tests/google/test_config.py +114 -0
- owid_datautils-0.6.1/tests/google/test_sheets.py +89 -0
- owid_datautils-0.6.1/tests/io/test_archive.py +215 -0
- owid_datautils-0.6.1/tests/io/test_df.py +228 -0
- owid_datautils-0.6.1/tests/io/test_json.py +56 -0
- owid_datautils-0.6.1/tests/mocks.py +12 -0
- owid_datautils-0.6.1/tests/test_dataframes.py +1651 -0
- owid_datautils-0.6.1/tests/test_decorators.py +72 -0
- owid_datautils-0.6.1/tests/test_ui.py +28 -0
- owid_datautils-0.6.1/tests/test_web.py +89 -0
- owid_datautils-0.6.1/uv.lock +2248 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
coverage:
|
|
2
|
+
status:
|
|
3
|
+
project:
|
|
4
|
+
default:
|
|
5
|
+
target: auto
|
|
6
|
+
# adjust accordingly based on how flaky your tests are
|
|
7
|
+
# this allows a 10% drop from the previous base commit coverage
|
|
8
|
+
threshold: 3%
|
|
9
|
+
patch:
|
|
10
|
+
default:
|
|
11
|
+
target: auto
|
|
12
|
+
threshold: 3%
|
|
13
|
+
base: auto
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.8", "3.9", "3.10", "3.11"]
|
|
15
|
+
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v2
|
|
20
|
+
|
|
21
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
22
|
+
uses: actions/setup-python@v2
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install packages
|
|
27
|
+
run: |
|
|
28
|
+
make .venv
|
|
29
|
+
|
|
30
|
+
- name: Check formatting
|
|
31
|
+
run: |
|
|
32
|
+
make check-formatting
|
|
33
|
+
|
|
34
|
+
- name: Lint
|
|
35
|
+
run: |
|
|
36
|
+
make lint
|
|
37
|
+
|
|
38
|
+
- name: Check typing
|
|
39
|
+
run: |
|
|
40
|
+
make check-typing
|
|
41
|
+
|
|
42
|
+
- name: Unit test
|
|
43
|
+
run: |
|
|
44
|
+
make report-coverage
|
|
45
|
+
|
|
46
|
+
- name: "Coverage: Upload to codecov.io"
|
|
47
|
+
uses: codecov/codecov-action@v2
|
|
48
|
+
with:
|
|
49
|
+
fail_ci_if_error: true
|
|
50
|
+
verbose: true
|
|
51
|
+
files: coverage.xml
|
|
52
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
# Usually these files are written by a python script from a template
|
|
32
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
33
|
+
*.manifest
|
|
34
|
+
*.spec
|
|
35
|
+
|
|
36
|
+
# Installer logs
|
|
37
|
+
pip-log.txt
|
|
38
|
+
pip-delete-this-directory.txt
|
|
39
|
+
|
|
40
|
+
# Unit test / coverage reports
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
nosetests.xml
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
*.py,cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
target/
|
|
76
|
+
|
|
77
|
+
# Jupyter Notebook
|
|
78
|
+
.ipynb_checkpoints
|
|
79
|
+
|
|
80
|
+
# IPython
|
|
81
|
+
profile_default/
|
|
82
|
+
ipython_config.py
|
|
83
|
+
|
|
84
|
+
# pyenv
|
|
85
|
+
.python-version
|
|
86
|
+
|
|
87
|
+
# pipenv
|
|
88
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
89
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
90
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
91
|
+
# install all needed dependencies.
|
|
92
|
+
#Pipfile.lock
|
|
93
|
+
|
|
94
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
95
|
+
__pypackages__/
|
|
96
|
+
|
|
97
|
+
# Celery stuff
|
|
98
|
+
celerybeat-schedule
|
|
99
|
+
celerybeat.pid
|
|
100
|
+
|
|
101
|
+
# SageMath parsed files
|
|
102
|
+
*.sage.py
|
|
103
|
+
|
|
104
|
+
# Environments
|
|
105
|
+
.env
|
|
106
|
+
.venv
|
|
107
|
+
env/
|
|
108
|
+
venv/
|
|
109
|
+
ENV/
|
|
110
|
+
env.bak/
|
|
111
|
+
venv.bak/
|
|
112
|
+
|
|
113
|
+
# Spyder project settings
|
|
114
|
+
.spyderproject
|
|
115
|
+
.spyproject
|
|
116
|
+
|
|
117
|
+
# Rope project settings
|
|
118
|
+
.ropeproject
|
|
119
|
+
|
|
120
|
+
# mkdocs documentation
|
|
121
|
+
/site
|
|
122
|
+
|
|
123
|
+
# mypy
|
|
124
|
+
.mypy_cache/
|
|
125
|
+
.dmypy.json
|
|
126
|
+
dmypy.json
|
|
127
|
+
|
|
128
|
+
# Pyre type checker
|
|
129
|
+
.pyre/
|
|
130
|
+
|
|
131
|
+
# PyCharm config
|
|
132
|
+
.idea
|
|
133
|
+
|
|
134
|
+
# Mac hidden files
|
|
135
|
+
.DS_Store
|
|
136
|
+
|
|
137
|
+
# reports (coverage, linting)
|
|
138
|
+
.reports/
|
|
139
|
+
|
|
140
|
+
# Google
|
|
141
|
+
client_secret*
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
- id: format
|
|
5
|
+
name: format
|
|
6
|
+
entry: make format
|
|
7
|
+
language: system
|
|
8
|
+
- id: lint
|
|
9
|
+
name: lint
|
|
10
|
+
entry: make lint
|
|
11
|
+
language: system
|
|
12
|
+
- id: check-typing
|
|
13
|
+
name: check-typing
|
|
14
|
+
entry: make check-typing
|
|
15
|
+
language: system
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Read the Docs configuration file
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
3
|
+
|
|
4
|
+
# Required
|
|
5
|
+
version: 2
|
|
6
|
+
|
|
7
|
+
# Set the version of Python and other tools you might need
|
|
8
|
+
build:
|
|
9
|
+
os: ubuntu-20.04
|
|
10
|
+
tools: {python: "3.8"}
|
|
11
|
+
jobs:
|
|
12
|
+
pre_create_environment:
|
|
13
|
+
- asdf plugin add poetry
|
|
14
|
+
- asdf install poetry latest
|
|
15
|
+
- asdf global poetry latest
|
|
16
|
+
- poetry config virtualenvs.create false
|
|
17
|
+
post_install:
|
|
18
|
+
- poetry install
|
|
19
|
+
|
|
20
|
+
# Build documentation in the docs/ directory with Sphinx
|
|
21
|
+
sphinx:
|
|
22
|
+
configuration: docs/conf.py
|
|
23
|
+
fail_on_warning: true
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Global Change Data Lab
|
|
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.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: owid-datautils
|
|
3
|
+
Version: 0.6.1
|
|
4
|
+
Summary: Data utils library by the Data Team at Our World in Data
|
|
5
|
+
Author-email: Our World in Data <tech@ourworldindata.org>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: data cleaning,data processing,data utils,our world in data
|
|
9
|
+
Requires-Python: <4.0,>=3.10
|
|
10
|
+
Requires-Dist: boto3>=1.38.23
|
|
11
|
+
Requires-Dist: click>=8.1.7
|
|
12
|
+
Requires-Dist: colorama>=0.4.4
|
|
13
|
+
Requires-Dist: gdown>=4.5.2
|
|
14
|
+
Requires-Dist: gsheets>=0.6.1
|
|
15
|
+
Requires-Dist: pandas>=2.2.3
|
|
16
|
+
Requires-Dist: py7zr>=0.22.0
|
|
17
|
+
Requires-Dist: pyarrow>=18.0.0
|
|
18
|
+
Requires-Dist: pydrive2>=1.15.0
|
|
19
|
+
Requires-Dist: structlog>=21.5.0
|
|
20
|
+
Requires-Dist: urllib3<2
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# owid-datautils
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
[](https://buildkite.com/our-world-in-data/owid-datautils-unit-tests)
|
|
6
|
+
[](https://docs.owid.io/projects/owid-datautils/en/latest/?badge=latest)
|
|
7
|
+
|
|
8
|
+
**owid-datautils** is a library to support the work of the Data Team at Our World in Data.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
pip install owid-datautils
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or install the latest development version directly from GitHub:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
pip install git+https://github.com/owid/etl.git#subdirectory=lib/datautils
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Development
|
|
23
|
+
|
|
24
|
+
### Pre-requisites
|
|
25
|
+
|
|
26
|
+
You need Python 3.10+, `UV` and `make` installed.
|
|
27
|
+
|
|
28
|
+
### Install in development mode
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
make .venv
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Test the code
|
|
35
|
+
|
|
36
|
+
Run:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
# run all unit tests and CI checks
|
|
40
|
+
make test
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Other useful commands
|
|
44
|
+
|
|
45
|
+
#### Code Quality
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
make check
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Format, lint, and typecheck changed files from master branch using `ruff` and `pyright`.
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
make format
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Format code using `ruff`.
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
make lint
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Lint code using `ruff`.
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
make check-typing
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Run type checking using `pyright`.
|
|
70
|
+
|
|
71
|
+
#### Coverage
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
make coverage
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Run unit tests with coverage reporting.
|
|
78
|
+
|
|
79
|
+
#### Versioning
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
make bump [part]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Upgrade version in all files where it appears. `[part]` can be `patch`, `minor` ad `major`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Minimal makefile for Sphinx documentation
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
# You can set these variables from the command line, and also
|
|
5
|
+
# from the environment for the first two.
|
|
6
|
+
SPHINXOPTS ?=
|
|
7
|
+
SPHINXBUILD ?= sphinx-build
|
|
8
|
+
SOURCEDIR = .
|
|
9
|
+
BUILDDIR = _build
|
|
10
|
+
|
|
11
|
+
# Put it first so that "make" without argument is like "make help".
|
|
12
|
+
help:
|
|
13
|
+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
14
|
+
|
|
15
|
+
.PHONY: help Makefile
|
|
16
|
+
|
|
17
|
+
# Catch-all target: route all unknown targets to Sphinx using the new
|
|
18
|
+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
|
19
|
+
%: Makefile
|
|
20
|
+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{%- macro automodule(modname, options) -%}
|
|
2
|
+
.. automodule:: {{ modname }}
|
|
3
|
+
{%- for option in options %}
|
|
4
|
+
:{{ option }}:
|
|
5
|
+
{%- endfor %}
|
|
6
|
+
{%- endmacro %}
|
|
7
|
+
|
|
8
|
+
{%- macro toctree(docnames) -%}
|
|
9
|
+
.. toctree::
|
|
10
|
+
:maxdepth: {{ maxdepth }}
|
|
11
|
+
{% for docname in docnames %}
|
|
12
|
+
{{ docname }}
|
|
13
|
+
{%- endfor %}
|
|
14
|
+
{%- endmacro %}
|
|
15
|
+
|
|
16
|
+
{%- if is_namespace %}
|
|
17
|
+
{{- [pkgname, "namespace"] | join(" ") | e | heading }}
|
|
18
|
+
{% else %}
|
|
19
|
+
{{- pkgname | e | heading }}
|
|
20
|
+
{% endif %}
|
|
21
|
+
|
|
22
|
+
{%- if is_namespace %}
|
|
23
|
+
.. py:module:: {{ pkgname }}
|
|
24
|
+
{% endif %}
|
|
25
|
+
|
|
26
|
+
{%- if modulefirst and not is_namespace %}
|
|
27
|
+
{{ automodule(pkgname, automodule_options) }}
|
|
28
|
+
{% endif %}
|
|
29
|
+
|
|
30
|
+
{%- if subpackages %}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
{{ toctree(subpackages) }}
|
|
34
|
+
{% endif %}
|
|
35
|
+
|
|
36
|
+
{%- if submodules %}
|
|
37
|
+
{% if separatemodules %}
|
|
38
|
+
{{ toctree(submodules) }}
|
|
39
|
+
{% else %}
|
|
40
|
+
{%- for submodule in submodules %}
|
|
41
|
+
{% if show_headings %}
|
|
42
|
+
{{- submodule | e | heading(2) }}
|
|
43
|
+
{% endif %}
|
|
44
|
+
{{ automodule(submodule, automodule_options) }}
|
|
45
|
+
{% endfor %}
|
|
46
|
+
{%- endif %}
|
|
47
|
+
{%- endif %}
|
|
48
|
+
|
|
49
|
+
{%- if not modulefirst and not is_namespace %}
|
|
50
|
+
|
|
51
|
+
{{ automodule(pkgname, automodule_options) }}
|
|
52
|
+
{% endif %}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Configuration file for the Sphinx documentation builder.
|
|
2
|
+
#
|
|
3
|
+
# This file only contains a selection of the most common options. For a full
|
|
4
|
+
# list see the documentation:
|
|
5
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
6
|
+
|
|
7
|
+
# -- Path setup --------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# If extensions (or modules to document with autodoc) are in another directory,
|
|
10
|
+
# add these directories to sys.path here. If the directory is relative to the
|
|
11
|
+
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
12
|
+
#
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
sys.path.insert(0, os.path.abspath(os.path.join("../owid/")))
|
|
17
|
+
|
|
18
|
+
# -- Project information -----------------------------------------------------
|
|
19
|
+
|
|
20
|
+
project = "owid-datautils"
|
|
21
|
+
copyright = "2022, Our World in Data"
|
|
22
|
+
author = "Our World in Data"
|
|
23
|
+
|
|
24
|
+
# The full version, including alpha/beta/rc tags
|
|
25
|
+
release = "0.5.3"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# -- General configuration ---------------------------------------------------
|
|
29
|
+
|
|
30
|
+
# Add any Sphinx extension module names here, as strings. They can be
|
|
31
|
+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
32
|
+
# ones.
|
|
33
|
+
extensions = [
|
|
34
|
+
"sphinx.ext.autodoc",
|
|
35
|
+
"sphinx.ext.autosummary",
|
|
36
|
+
"sphinx.ext.napoleon",
|
|
37
|
+
"sphinx.ext.viewcode",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
# Add any paths that contain templates here, relative to this directory.
|
|
41
|
+
templates_path = ["_templates"]
|
|
42
|
+
|
|
43
|
+
# List of patterns, relative to source directory, that match files and
|
|
44
|
+
# directories to ignore when looking for source files.
|
|
45
|
+
# This pattern also affects html_static_path and html_extra_path.
|
|
46
|
+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "api/modules.rst"]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# -- Options for HTML output -------------------------------------------------
|
|
50
|
+
|
|
51
|
+
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
52
|
+
# a list of builtin themes.
|
|
53
|
+
#
|
|
54
|
+
html_theme = "furo"
|
|
55
|
+
|
|
56
|
+
html_theme_options = {
|
|
57
|
+
"sidebar_hide_name": True,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Add any paths that contain custom static files (such as style sheets) here,
|
|
61
|
+
# relative to this directory. They are copied after the builtin static files,
|
|
62
|
+
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
63
|
+
html_static_path = ["_static"]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
html_logo = "_static/owid.png"
|
|
67
|
+
html_favicon = "_static/favicon.ico"
|
|
68
|
+
|
|
69
|
+
autodoc_default_flags = [
|
|
70
|
+
"members",
|
|
71
|
+
"undoc-members",
|
|
72
|
+
"private-members",
|
|
73
|
+
"special-members",
|
|
74
|
+
"inherited-members",
|
|
75
|
+
"show-inheritance",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
html_context = {
|
|
79
|
+
"display_github": True, # Integrate GitHub
|
|
80
|
+
"github_user": "owid", # Username
|
|
81
|
+
"github_repo": "owid-datautils-py", # Repo name
|
|
82
|
+
"github_version": "main", # Version
|
|
83
|
+
"conf_py_path": "docs/", # Path in the checkout to the docs root
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
## API docs
|
|
87
|
+
from sphinx.ext.apidoc import main
|
|
88
|
+
|
|
89
|
+
# uv run sphinx-apidoc --help
|
|
90
|
+
main(["-f", "-e", "-t", "apidoc-templates", "-P", "-o", "api", "../owid/"])
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
.. owid-datautils documentation master file, created by
|
|
2
|
+
sphinx-quickstart on Wed Jun 1 23:00:03 2022.
|
|
3
|
+
You can adapt this file completely to your liking, but it should at least
|
|
4
|
+
contain the root `toctree` directive.
|
|
5
|
+
|
|
6
|
+
owid-datautils
|
|
7
|
+
==========================================
|
|
8
|
+
|
|
9
|
+
.. toctree::
|
|
10
|
+
:maxdepth: 2
|
|
11
|
+
|
|
12
|
+
owid.datautils <api/datautils>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@ECHO OFF
|
|
2
|
+
|
|
3
|
+
pushd %~dp0
|
|
4
|
+
|
|
5
|
+
REM Command file for Sphinx documentation
|
|
6
|
+
|
|
7
|
+
if "%SPHINXBUILD%" == "" (
|
|
8
|
+
set SPHINXBUILD=sphinx-build
|
|
9
|
+
)
|
|
10
|
+
set SOURCEDIR=.
|
|
11
|
+
set BUILDDIR=_build
|
|
12
|
+
|
|
13
|
+
%SPHINXBUILD% >NUL 2>NUL
|
|
14
|
+
if errorlevel 9009 (
|
|
15
|
+
echo.
|
|
16
|
+
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
|
17
|
+
echo.installed, then set the SPHINXBUILD environment variable to point
|
|
18
|
+
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
|
19
|
+
echo.may add the Sphinx directory to PATH.
|
|
20
|
+
echo.
|
|
21
|
+
echo.If you don't have Sphinx installed, grab it from
|
|
22
|
+
echo.https://www.sphinx-doc.org/
|
|
23
|
+
exit /b 1
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
if "%1" == "" goto help
|
|
27
|
+
|
|
28
|
+
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
29
|
+
goto end
|
|
30
|
+
|
|
31
|
+
:help
|
|
32
|
+
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
33
|
+
|
|
34
|
+
:end
|
|
35
|
+
popd
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Utils related to sanity checks of datasets."""
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Common objects shared by other modules."""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
from typing import Any, List, Set, Union, cast
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ExceptionFromDocstring(Exception):
|
|
8
|
+
"""Exception that returns its own docstring, if no message is explicitly given."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, exception_message: Union[str, None] = None, *args: Any):
|
|
11
|
+
super().__init__(exception_message or self.__doc__, *args)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ExceptionFromDocstringWithKwargs(Exception):
|
|
15
|
+
"""Exception that returns its own docstring, if no message is explicitly given."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, exception_message: Union[str, None] = None, *args: Any, **kwargs: Any):
|
|
18
|
+
text = cast(str, exception_message or self.__doc__)
|
|
19
|
+
if kwargs:
|
|
20
|
+
additional_text = ", ".join([f"{key}: {value}" for key, value in kwargs.items()])
|
|
21
|
+
if additional_text is not None:
|
|
22
|
+
text += " " + additional_text
|
|
23
|
+
super().__init__(text, *args)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def warn_on_list_of_entities(
|
|
27
|
+
list_of_entities: Union[List[Any], Set[Any]], warning_message: str, show_list: bool
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Raise a warning with a custom message, and optionally print a list of affected elements.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
list_of_entities : list or set
|
|
34
|
+
Elements to optionally print one by one (only relevant if show_list is True).
|
|
35
|
+
warning_message : str
|
|
36
|
+
Warning message.
|
|
37
|
+
show_list : bool
|
|
38
|
+
True to print a list of affected entities.
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
warnings.warn(warning_message)
|
|
42
|
+
if show_list:
|
|
43
|
+
print(warning_message)
|
|
44
|
+
print("\n".join(["* " + str(entity) for entity in list_of_entities]))
|