eolas-data 1.7.0__tar.gz → 1.9.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.
- {eolas_data-1.7.0 → eolas_data-1.9.0}/.github/workflows/catalog-drift.yml +1 -1
- eolas_data-1.9.0/.github/workflows/pre-release.yml +50 -0
- eolas_data-1.9.0/.github/workflows/publish.yml +143 -0
- eolas_data-1.9.0/.github/workflows/smoke.yml +39 -0
- eolas_data-1.9.0/.github/workflows/test.yml +84 -0
- eolas_data-1.9.0/CHANGELOG.md +105 -0
- eolas_data-1.9.0/LICENSE +21 -0
- eolas_data-1.9.0/PKG-INFO +364 -0
- eolas_data-1.9.0/README.md +312 -0
- eolas_data-1.9.0/eolas_data/__init__.py +47 -0
- {eolas_data-1.7.0 → eolas_data-1.9.0}/eolas_data/_dataset_names.py +299 -43
- eolas_data-1.9.0/eolas_data/_regen_names.py +58 -0
- eolas_data-1.9.0/eolas_data/cdc.py +233 -0
- eolas_data-1.9.0/eolas_data/cli.py +1583 -0
- eolas_data-1.9.0/eolas_data/client.py +2796 -0
- eolas_data-1.9.0/eolas_data/console.py +25 -0
- {eolas_data-1.7.0 → eolas_data-1.9.0}/eolas_data/dataset.py +17 -3
- eolas_data-1.9.0/eolas_data/exceptions.py +94 -0
- eolas_data-1.9.0/eolas_data/library.py +408 -0
- eolas_data-1.9.0/eolas_data/meta.py +232 -0
- eolas_data-1.9.0/eolas_data/rows.py +36 -0
- {eolas_data-1.7.0 → eolas_data-1.9.0}/eolas_data/schedule.py +19 -8
- eolas_data-1.9.0/eolas_data/search.py +133 -0
- {eolas_data-1.7.0 → eolas_data-1.9.0}/pyproject.toml +23 -3
- eolas_data-1.9.0/scripts/check_client_contract.py +61 -0
- eolas_data-1.9.0/scripts/preflight.sh +43 -0
- eolas_data-1.9.0/tests/fixtures/source_helpers.json +37 -0
- eolas_data-1.9.0/tests/test_as_arrow.py +51 -0
- eolas_data-1.9.0/tests/test_cdc_roundtrip.py +166 -0
- eolas_data-1.9.0/tests/test_changes_http.py +74 -0
- {eolas_data-1.7.0 → eolas_data-1.9.0}/tests/test_cli.py +184 -3
- eolas_data-1.9.0/tests/test_client.py +692 -0
- eolas_data-1.9.0/tests/test_date_filter.py +81 -0
- eolas_data-1.9.0/tests/test_geometry_param.py +235 -0
- eolas_data-1.9.0/tests/test_get_local.py +276 -0
- eolas_data-1.9.0/tests/test_keyring.py +266 -0
- eolas_data-1.9.0/tests/test_library.py +235 -0
- eolas_data-1.9.0/tests/test_meta.py +101 -0
- eolas_data-1.9.0/tests/test_preview_dimensions.py +82 -0
- eolas_data-1.9.0/tests/test_progress.py +518 -0
- eolas_data-1.9.0/tests/test_resilience.py +95 -0
- eolas_data-1.9.0/tests/test_rows.py +24 -0
- {eolas_data-1.7.0 → eolas_data-1.9.0}/tests/test_schedule.py +10 -1
- eolas_data-1.9.0/tests/test_search.py +77 -0
- eolas_data-1.9.0/tests/test_smoke_live.py +85 -0
- eolas_data-1.9.0/tests/test_source_helpers.py +36 -0
- eolas_data-1.9.0/tests/test_sync_bulk.py +499 -0
- eolas_data-1.9.0/tests/test_sync_changes.py +791 -0
- eolas_data-1.7.0/.github/workflows/publish.yml +0 -31
- eolas_data-1.7.0/PKG-INFO +0 -216
- eolas_data-1.7.0/README.md +0 -174
- eolas_data-1.7.0/eolas_data/__init__.py +0 -16
- eolas_data-1.7.0/eolas_data/_regen_names.py +0 -57
- eolas_data-1.7.0/eolas_data/cli.py +0 -639
- eolas_data-1.7.0/eolas_data/client.py +0 -400
- eolas_data-1.7.0/eolas_data/exceptions.py +0 -20
- eolas_data-1.7.0/tests/test_client.py +0 -337
- {eolas_data-1.7.0 → eolas_data-1.9.0}/.gitignore +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Pre-release gate
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
gate:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
env:
|
|
10
|
+
PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v5
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.12"
|
|
16
|
+
|
|
17
|
+
- name: Client contract matrix
|
|
18
|
+
run: python scripts/check_client_contract.py
|
|
19
|
+
|
|
20
|
+
- name: Build + install wheel
|
|
21
|
+
run: |
|
|
22
|
+
pip install build
|
|
23
|
+
python -m build
|
|
24
|
+
WHL=$(ls -1 dist/*.whl | head -1)
|
|
25
|
+
pip install "$WHL"
|
|
26
|
+
pip install pytest responses geopandas shapely pandas pyarrow typer rich keyring
|
|
27
|
+
|
|
28
|
+
- name: Unit tests (installed package)
|
|
29
|
+
run: pytest -q -m "not integration"
|
|
30
|
+
|
|
31
|
+
- name: Live smoke
|
|
32
|
+
env:
|
|
33
|
+
EOLAS_API_KEY: ${{ secrets.EOLAS_API_KEY }}
|
|
34
|
+
run: |
|
|
35
|
+
if [ -z "$EOLAS_API_KEY" ]; then
|
|
36
|
+
echo "::error::EOLAS_API_KEY secret required for pre-release smoke."
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
pytest -q -m integration tests/test_smoke_live.py
|
|
40
|
+
|
|
41
|
+
- name: Version parity with eolas-r
|
|
42
|
+
run: |
|
|
43
|
+
set -euo pipefail
|
|
44
|
+
py_ver=$(grep -E '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
|
|
45
|
+
r_ver=$(curl -fsSL "https://raw.githubusercontent.com/phildonovan/eolas-r/master/DESCRIPTION" \
|
|
46
|
+
| awk -F': ' '/^Version:/{print $2; exit}')
|
|
47
|
+
echo "Python: $py_ver | R (master): $r_ver"
|
|
48
|
+
if [ "$py_ver" != "$r_ver" ]; then
|
|
49
|
+
echo "::warning::Client versions differ — bump both before tagging if shipping related fixes"
|
|
50
|
+
fi
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
version-parity:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v5
|
|
13
|
+
- name: Compare tag to eolas-r DESCRIPTION
|
|
14
|
+
env:
|
|
15
|
+
TAG: ${{ github.ref_name }}
|
|
16
|
+
run: |
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
expected="${TAG#v}"
|
|
19
|
+
r_ver=$(curl -fsSL "https://raw.githubusercontent.com/phildonovan/eolas-r/master/DESCRIPTION" \
|
|
20
|
+
| awk -F': ' '/^Version:/{print $2; exit}')
|
|
21
|
+
py_ver=$(grep -E '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
|
|
22
|
+
echo "Tag: $expected | R: $r_ver | Python (pyproject): $py_ver"
|
|
23
|
+
if [ "$expected" != "$py_ver" ]; then
|
|
24
|
+
echo "::error::Tag $TAG does not match pyproject.toml version $py_ver"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
if [ "$expected" != "$r_ver" ]; then
|
|
28
|
+
echo "::warning::R package version ($r_ver) differs from tag ($expected) — align releases when possible"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
- name: Guard — version must not already exist on PyPI
|
|
32
|
+
env:
|
|
33
|
+
TAG: ${{ github.ref_name }}
|
|
34
|
+
run: |
|
|
35
|
+
# PyPI permanently reserves a filename once uploaded, INCLUDING for
|
|
36
|
+
# yanked releases — a yanked version can never be re-published. This
|
|
37
|
+
# repo has a burned band at 1.5.0-1.8.0 (uploaded May 2026, yanked),
|
|
38
|
+
# and development later resumed BELOW it on the 1.3.x line, so a naive
|
|
39
|
+
# minor bump can walk straight back into it. Without this guard that
|
|
40
|
+
# failure surfaces only at the upload step, after a full build+test,
|
|
41
|
+
# as an opaque "400 File already exists".
|
|
42
|
+
set -euo pipefail
|
|
43
|
+
expected="${TAG#v}"
|
|
44
|
+
taken=$(curl -fsSL "https://pypi.org/pypi/eolas-data/json" \
|
|
45
|
+
| python3 -c "import json,sys; print('yes' if '$expected' in json.load(sys.stdin)['releases'] else 'no')")
|
|
46
|
+
if [ "$taken" = "yes" ]; then
|
|
47
|
+
echo "::error::Version $expected already exists on PyPI (possibly yanked)."
|
|
48
|
+
echo "::error::Yanked versions permanently reserve their filenames and cannot be re-published."
|
|
49
|
+
echo "::error::Pick a version above every existing release and re-tag."
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
echo "Version $expected is free on PyPI."
|
|
53
|
+
|
|
54
|
+
test:
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
needs: version-parity
|
|
57
|
+
env:
|
|
58
|
+
PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v5
|
|
61
|
+
|
|
62
|
+
- uses: actions/setup-python@v5
|
|
63
|
+
with:
|
|
64
|
+
python-version: "3.12"
|
|
65
|
+
|
|
66
|
+
- name: Build wheel
|
|
67
|
+
run: pip install build && python -m build
|
|
68
|
+
|
|
69
|
+
- name: Install wheel + test deps
|
|
70
|
+
run: |
|
|
71
|
+
WHL=$(ls -1 dist/*.whl | head -1)
|
|
72
|
+
pip install "$WHL"
|
|
73
|
+
pip install pytest responses geopandas shapely pandas pyarrow typer rich keyring
|
|
74
|
+
|
|
75
|
+
- name: Version self-report parity (REL-1)
|
|
76
|
+
env:
|
|
77
|
+
TAG: ${{ github.ref_name }}
|
|
78
|
+
run: |
|
|
79
|
+
set -euo pipefail
|
|
80
|
+
expected="${TAG#v}"
|
|
81
|
+
# __version__ is read from installed distribution metadata, so this
|
|
82
|
+
# asserts the wheel the user pip-installs self-reports the tag — the
|
|
83
|
+
# exact drift (shipped 1.3.21 said 1.3.20) that this gate structurally
|
|
84
|
+
# closes. Run from /tmp so the source tree's __init__ can't shadow.
|
|
85
|
+
reported=$(cd /tmp && python -c "import eolas_data; print(eolas_data.__version__)")
|
|
86
|
+
echo "Tag: $expected | __version__: $reported"
|
|
87
|
+
if [ "$reported" != "$expected" ]; then
|
|
88
|
+
echo "::error::Installed eolas_data.__version__ ($reported) != tag ($expected)"
|
|
89
|
+
exit 1
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
- name: Client contract matrix
|
|
93
|
+
run: python scripts/check_client_contract.py
|
|
94
|
+
|
|
95
|
+
- name: pytest
|
|
96
|
+
run: pytest -q -m "not integration"
|
|
97
|
+
|
|
98
|
+
smoke:
|
|
99
|
+
runs-on: ubuntu-latest
|
|
100
|
+
needs: test
|
|
101
|
+
steps:
|
|
102
|
+
- uses: actions/checkout@v5
|
|
103
|
+
- uses: actions/setup-python@v5
|
|
104
|
+
with:
|
|
105
|
+
python-version: "3.12"
|
|
106
|
+
- name: Install package from tag
|
|
107
|
+
run: pip install ".[dev,geo]"
|
|
108
|
+
- name: Live smoke (pre-publish gate)
|
|
109
|
+
env:
|
|
110
|
+
EOLAS_API_KEY: ${{ secrets.EOLAS_API_KEY }}
|
|
111
|
+
run: |
|
|
112
|
+
if [ -z "$EOLAS_API_KEY" ]; then
|
|
113
|
+
echo "::warning::EOLAS_API_KEY not set — skipping publish smoke"
|
|
114
|
+
exit 0
|
|
115
|
+
fi
|
|
116
|
+
pytest -q -m integration tests/test_smoke_live.py
|
|
117
|
+
|
|
118
|
+
publish:
|
|
119
|
+
needs: [test, smoke]
|
|
120
|
+
if: needs.test.result == 'success'
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
environment: pypi
|
|
123
|
+
permissions:
|
|
124
|
+
id-token: write
|
|
125
|
+
|
|
126
|
+
steps:
|
|
127
|
+
- uses: actions/checkout@v5
|
|
128
|
+
|
|
129
|
+
- uses: actions/setup-python@v5
|
|
130
|
+
with:
|
|
131
|
+
python-version: "3.12"
|
|
132
|
+
|
|
133
|
+
- name: Install build tools
|
|
134
|
+
run: pip install build
|
|
135
|
+
|
|
136
|
+
- name: Build
|
|
137
|
+
run: python -m build
|
|
138
|
+
|
|
139
|
+
- name: Publish to PyPI
|
|
140
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
141
|
+
with:
|
|
142
|
+
# Uses PYPI_API_TOKEN when set; otherwise OIDC trusted publishing.
|
|
143
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Live API smoke
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 8 * * 1" # Mondays 08:00 UTC
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
smoke:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v5
|
|
13
|
+
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.12"
|
|
17
|
+
|
|
18
|
+
- name: Require API key on manual runs
|
|
19
|
+
if: github.event_name == 'workflow_dispatch'
|
|
20
|
+
env:
|
|
21
|
+
EOLAS_API_KEY: ${{ secrets.EOLAS_API_KEY }}
|
|
22
|
+
run: |
|
|
23
|
+
if [ -z "$EOLAS_API_KEY" ]; then
|
|
24
|
+
echo "::error::EOLAS_API_KEY secret is required for workflow_dispatch smoke runs."
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
- name: Install package + dev/geo deps (as users would)
|
|
29
|
+
run: pip install ".[dev,geo]"
|
|
30
|
+
|
|
31
|
+
- name: Live smoke tests
|
|
32
|
+
env:
|
|
33
|
+
EOLAS_API_KEY: ${{ secrets.EOLAS_API_KEY }}
|
|
34
|
+
run: |
|
|
35
|
+
if [ -z "$EOLAS_API_KEY" ]; then
|
|
36
|
+
echo "EOLAS_API_KEY secret not configured — skipping scheduled smoke tests."
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
pytest -q -m integration tests/test_smoke_live.py
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
contract:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v5
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.12"
|
|
16
|
+
- name: Client contract matrix
|
|
17
|
+
run: python scripts/check_client_contract.py
|
|
18
|
+
|
|
19
|
+
test:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
needs: contract
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
python-version: ["3.10", "3.12", "3.13"]
|
|
26
|
+
env:
|
|
27
|
+
PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v5
|
|
30
|
+
|
|
31
|
+
- uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python-version }}
|
|
34
|
+
|
|
35
|
+
- name: Install package + dev + geo + secure (editable)
|
|
36
|
+
run: pip install -e ".[dev,geo,secure]"
|
|
37
|
+
|
|
38
|
+
- name: pytest (unit suite)
|
|
39
|
+
run: pytest -q -m "not integration"
|
|
40
|
+
|
|
41
|
+
test-installed:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
needs: contract
|
|
44
|
+
env:
|
|
45
|
+
PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v5
|
|
48
|
+
|
|
49
|
+
- uses: actions/setup-python@v5
|
|
50
|
+
with:
|
|
51
|
+
python-version: "3.12"
|
|
52
|
+
|
|
53
|
+
- name: Build wheel
|
|
54
|
+
run: pip install build && python -m build
|
|
55
|
+
|
|
56
|
+
- name: Install built wheel + test deps (as users would)
|
|
57
|
+
run: |
|
|
58
|
+
WHL=$(ls -1 dist/*.whl | head -1)
|
|
59
|
+
pip install "$WHL"
|
|
60
|
+
pip install pytest responses geopandas shapely pandas pyarrow typer rich keyring
|
|
61
|
+
|
|
62
|
+
- name: pytest on installed package
|
|
63
|
+
run: pytest -q -m "not integration"
|
|
64
|
+
|
|
65
|
+
coverage:
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
needs: contract
|
|
68
|
+
permissions:
|
|
69
|
+
id-token: write
|
|
70
|
+
env:
|
|
71
|
+
PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring
|
|
72
|
+
steps:
|
|
73
|
+
- uses: actions/checkout@v5
|
|
74
|
+
- uses: actions/setup-python@v5
|
|
75
|
+
with:
|
|
76
|
+
python-version: "3.12"
|
|
77
|
+
- run: pip install -e ".[dev,geo,secure]" pytest-cov
|
|
78
|
+
- run: pytest -q -m "not integration" --cov=eolas_data --cov-report=xml
|
|
79
|
+
- name: Upload coverage
|
|
80
|
+
uses: codecov/codecov-action@v5
|
|
81
|
+
with:
|
|
82
|
+
files: coverage.xml
|
|
83
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
84
|
+
fail_ci_if_error: false
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `eolas-data` are recorded here. This project follows
|
|
4
|
+
[Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## 1.9.0
|
|
7
|
+
|
|
8
|
+
> Version jumps 1.4.0 -> 1.9.0. PyPI versions 1.5.0-1.8.0 were uploaded in May
|
|
9
|
+
> 2026 and later yanked; yanked filenames are permanently reserved, so those
|
|
10
|
+
> numbers can never be published again. The 1.9.0 jump clears the band for good.
|
|
11
|
+
> The R client moves to 1.9.0 at the same time so the two stay aligned.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`geometry=False` on `get()`** — omit the `geometry_wkt` column. Two-thirds of
|
|
17
|
+
eolas datasets (1017/1536) carry geometry, and on TA/RC boundary tables the WKT
|
|
18
|
+
dwarfs the attributes. The column is projected away at the API's storage layer,
|
|
19
|
+
so it is never read from S3 or transferred — this cuts I/O, not just payload.
|
|
20
|
+
Responses carry `X-Eolas-Geometry-Omitted: true`.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **Whole-dataset pulls of small spatial tables stay on the live path when
|
|
25
|
+
`geometry=False`.** Geometry was one of the two triggers for the API's
|
|
26
|
+
large-dataset (413) guard, so `get("some_boundary_table")` was transparently
|
|
27
|
+
diverted to a bulk download. The client now mirrors the server's relaxed guard.
|
|
28
|
+
The row-count trigger is unchanged — dropping a column doesn't reduce row count.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **`geometry=False` is now honoured on the bulk-routed path.** A spatial table
|
|
33
|
+
over the 100k-row threshold stays "blocked" even with `geometry=False`, so
|
|
34
|
+
`get()` routes it to the bulk cache — which has no server-side projection. The
|
|
35
|
+
flag was dropped at that hand-off, so the caller silently received the full
|
|
36
|
+
geometry-bearing file and, with `as_geo=None`, an auto-converted GeoDataFrame.
|
|
37
|
+
Found in peer review.
|
|
38
|
+
- **The in-memory response cache now keys on `geometry`.** Without it,
|
|
39
|
+
`get(x)` and `get(x, geometry=False)` shared a cache key, so whichever ran
|
|
40
|
+
second silently returned the other's shape (a whole column different). Only
|
|
41
|
+
reachable with `Client(cache=True)`.
|
|
42
|
+
|
|
43
|
+
## 1.4.0
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- **`Client.preview(name)`** — up to 10 sample rows via the unauthenticated
|
|
48
|
+
`/preview` endpoint. No API key required, no rate-limit cost, geometry hidden.
|
|
49
|
+
`eolas datasets preview` now uses it instead of burning an authenticated,
|
|
50
|
+
rate-limited `/data` call (DRIFT-5).
|
|
51
|
+
- **`dimensions=` filter on `get()`** and `eolas get --dimensions` — a
|
|
52
|
+
case-insensitive substring filter on dimension columns, applied server-side on
|
|
53
|
+
the live `/data` path (the filter was live in prod but exposed by no client;
|
|
54
|
+
DRIFT-4).
|
|
55
|
+
|
|
56
|
+
## 1.3.22
|
|
57
|
+
|
|
58
|
+
Network-hardening + correctness release, addressing findings from the
|
|
59
|
+
2026-07-05 client-library audit.
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- **Request timeouts everywhere (EH-1).** Every HTTP call now carries a default
|
|
64
|
+
`(10, 300)` second (connect, read) timeout via a session subclass. A
|
|
65
|
+
black-holed connection raises instead of hanging the caller forever. Override
|
|
66
|
+
with `Client(timeout=...)`.
|
|
67
|
+
- **Clean errors on transport failures (EH-2).** Connection refused / DNS /
|
|
68
|
+
timeout / reset now surface as `EolasError("Network error talking to
|
|
69
|
+
api.eolas.fyi: ...")` instead of a raw urllib3 traceback. The CLI's existing
|
|
70
|
+
error handler renders them cleanly.
|
|
71
|
+
- **Atomic downloads (EH-5).** `download()` / `download_bulk()` write to a temp
|
|
72
|
+
file and atomically rename on success, and verify bytes received against
|
|
73
|
+
`Content-Length`. An interrupted or truncated download now leaves **no file**
|
|
74
|
+
at the final path instead of a silent partial.
|
|
75
|
+
- **`get()` no longer degrades a bulk failure to a misleading 413 (EH-3).** The
|
|
76
|
+
auto-route swallow is narrowed to the routing decision; a real failure in the
|
|
77
|
+
bulk path now propagates instead of falling through to "use bulk download".
|
|
78
|
+
- **Arrow negotiation no longer masks real errors (EH-7).** An auth/404/429
|
|
79
|
+
during the Arrow attempt now propagates immediately, without the bogus "Arrow
|
|
80
|
+
IPC unavailable" nag and without re-sending the failed request as JSON. Only a
|
|
81
|
+
non-Arrow 200 or a genuine pyarrow/IPC decode error downgrades the session.
|
|
82
|
+
- **Watermark floor parsed correctly (DRIFT-2).** The HTTP 410 re-baseline
|
|
83
|
+
response nests its fields under `detail`; `WatermarkExpired.min_available_seq`
|
|
84
|
+
was always 0. Now read from the correct level with a top-level fallback.
|
|
85
|
+
- **No more pandas-3 warning on every `get()` (PY-3).** Metadata accessors are
|
|
86
|
+
set via `object.__setattr__`, bypassing the pandas 3 `UserWarning`.
|
|
87
|
+
- **Orphaned partial downloads are swept (PY-5).** `*.eolas-tmp-*` files >24h
|
|
88
|
+
old are cleaned on download start; a full `cache_clear()` removes them all.
|
|
89
|
+
- **`download()` docstring corrected (PY-1).** It no longer claims to work for
|
|
90
|
+
"all datasets" — it is the live path and 413s on whole-dataset pulls of
|
|
91
|
+
large/geo tables; use `get()` or `download_bulk()` there.
|
|
92
|
+
- **`eolas datasets list` no longer renders a blank ghost column (CLI-1).** On
|
|
93
|
+
narrow (<100 col) terminals the title column is dropped with a hint instead of
|
|
94
|
+
being squeezed to zero width.
|
|
95
|
+
- **Bulk-download docs corrected (DRIFT-3).** `download_bulk()` / the CLI
|
|
96
|
+
`--freshness` help no longer claim Free plans get monthly bulk — bulk is
|
|
97
|
+
Pro/Enterprise and Free keys receive HTTP 402.
|
|
98
|
+
|
|
99
|
+
### Changed
|
|
100
|
+
|
|
101
|
+
- **Single-sourced version (REL-1).** `__version__` is read from installed
|
|
102
|
+
distribution metadata, so it can never drift from `pyproject.toml` again
|
|
103
|
+
(shipped 1.3.21 previously self-reported 1.3.20). The publish workflow asserts
|
|
104
|
+
the installed `__version__` equals the release tag.
|
|
105
|
+
- **`merge_changes` is now a public export (DRIFT-6)** — added to `__all__`.
|
eolas_data-1.9.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Virtus Solutions
|
|
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.
|