eolas-data 1.2.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.2.0/.github/workflows/catalog-drift.yml +101 -0
- eolas_data-1.2.0/.github/workflows/publish.yml +31 -0
- eolas_data-1.2.0/.gitignore +27 -0
- eolas_data-1.2.0/PKG-INFO +214 -0
- eolas_data-1.2.0/README.md +170 -0
- eolas_data-1.2.0/eolas_data/__init__.py +16 -0
- eolas_data-1.2.0/eolas_data/_dataset_names.py +1455 -0
- eolas_data-1.2.0/eolas_data/_regen_names.py +57 -0
- eolas_data-1.2.0/eolas_data/cli.py +617 -0
- eolas_data-1.2.0/eolas_data/client.py +333 -0
- eolas_data-1.2.0/eolas_data/dataset.py +66 -0
- eolas_data-1.2.0/eolas_data/exceptions.py +20 -0
- eolas_data-1.2.0/eolas_data/schedule.py +258 -0
- eolas_data-1.2.0/pyproject.toml +48 -0
- eolas_data-1.2.0/tests/test_cli.py +483 -0
- eolas_data-1.2.0/tests/test_client.py +324 -0
- eolas_data-1.2.0/tests/test_schedule.py +270 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
name: Catalog drift detector
|
|
2
|
+
|
|
3
|
+
# Pings when the live eolas.fyi catalog has gained namespaces or grown the
|
|
4
|
+
# dataset count significantly without a corresponding library release. Opens
|
|
5
|
+
# (or updates) a single tracking issue rather than spamming.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: "0 7 * * 1" # Mondays 07:00 UTC
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
issues: write
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
check:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.12"
|
|
25
|
+
|
|
26
|
+
- name: Compare live catalog to baseline
|
|
27
|
+
id: drift
|
|
28
|
+
run: |
|
|
29
|
+
python <<'PY'
|
|
30
|
+
import json, os, urllib.request
|
|
31
|
+
|
|
32
|
+
# Baseline = the snapshot we shipped in the last release.
|
|
33
|
+
# Drift = anything that's changed since.
|
|
34
|
+
import importlib.util, pathlib
|
|
35
|
+
spec = importlib.util.spec_from_file_location(
|
|
36
|
+
"_dataset_names",
|
|
37
|
+
pathlib.Path("eolas_data/_dataset_names.py"),
|
|
38
|
+
)
|
|
39
|
+
module = importlib.util.module_from_spec(spec)
|
|
40
|
+
spec.loader.exec_module(module)
|
|
41
|
+
baseline = set(module.ALL_NAMES)
|
|
42
|
+
baseline_date = module.CATALOG_SNAPSHOT_DATE
|
|
43
|
+
|
|
44
|
+
with urllib.request.urlopen("https://api.eolas.fyi/v1/datasets", timeout=30) as r:
|
|
45
|
+
live = json.load(r)
|
|
46
|
+
live_names = {d["name"] for d in live}
|
|
47
|
+
live_namespaces = sorted({d["namespace"] for d in live})
|
|
48
|
+
|
|
49
|
+
baseline_namespaces = sorted({n.split("_", 1)[0] for n in baseline}) # crude — better via release-time metadata
|
|
50
|
+
|
|
51
|
+
added = sorted(live_names - baseline)
|
|
52
|
+
removed = sorted(baseline - live_names)
|
|
53
|
+
new_count = len(live_names)
|
|
54
|
+
base_count = len(baseline)
|
|
55
|
+
delta_pct = (new_count - base_count) / max(base_count, 1) * 100
|
|
56
|
+
|
|
57
|
+
# Threshold for "interesting" drift
|
|
58
|
+
significant = (
|
|
59
|
+
len(added) >= 10
|
|
60
|
+
or len(removed) >= 1
|
|
61
|
+
or abs(delta_pct) >= 5.0
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
summary = (
|
|
65
|
+
f"Baseline (release {baseline_date}): {base_count} datasets\\n"
|
|
66
|
+
f"Live now: {new_count} datasets ({delta_pct:+.1f}%)\\n\\n"
|
|
67
|
+
f"Added ({len(added)}): {', '.join(added[:30])}"
|
|
68
|
+
f"{' ...' if len(added) > 30 else ''}\\n\\n"
|
|
69
|
+
f"Removed ({len(removed)}): {', '.join(removed) or 'none'}"
|
|
70
|
+
)
|
|
71
|
+
print(summary)
|
|
72
|
+
|
|
73
|
+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
|
74
|
+
f.write(f"significant={'true' if significant else 'false'}\n")
|
|
75
|
+
f.write(f"new_count={new_count}\n")
|
|
76
|
+
f.write(f"base_count={base_count}\n")
|
|
77
|
+
f.write("summary<<EOF\n")
|
|
78
|
+
f.write(summary.replace("\\n", "\n"))
|
|
79
|
+
f.write("\nEOF\n")
|
|
80
|
+
PY
|
|
81
|
+
|
|
82
|
+
- name: Open or update drift issue
|
|
83
|
+
if: steps.drift.outputs.significant == 'true'
|
|
84
|
+
env:
|
|
85
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
86
|
+
SUMMARY: ${{ steps.drift.outputs.summary }}
|
|
87
|
+
NEW_COUNT: ${{ steps.drift.outputs.new_count }}
|
|
88
|
+
BASE_COUNT: ${{ steps.drift.outputs.base_count }}
|
|
89
|
+
run: |
|
|
90
|
+
set -euo pipefail
|
|
91
|
+
TITLE="Catalog drift: ${BASE_COUNT} → ${NEW_COUNT} datasets"
|
|
92
|
+
BODY=$(printf 'The live API catalog has drifted from the shipped baseline.\n\n%s\n\n---\n\nIf this delta warrants a release: bump version, run `python -m eolas_data._regen_names`, commit, tag, push.\n' "$SUMMARY")
|
|
93
|
+
|
|
94
|
+
# Find an existing open drift issue (label `catalog-drift`) and update it; else create.
|
|
95
|
+
EXISTING=$(gh issue list --label catalog-drift --state open --json number --jq '.[0].number' || true)
|
|
96
|
+
if [ -n "$EXISTING" ]; then
|
|
97
|
+
gh issue edit "$EXISTING" --title "$TITLE" --body "$BODY"
|
|
98
|
+
else
|
|
99
|
+
gh label create catalog-drift --color BFD4F2 --description "Live catalog has drifted from shipped baseline" 2>/dev/null || true
|
|
100
|
+
gh issue create --title "$TITLE" --body "$BODY" --label catalog-drift
|
|
101
|
+
fi
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: pypi
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
|
|
22
|
+
- name: Install build tools
|
|
23
|
+
run: pip install hatchling build
|
|
24
|
+
|
|
25
|
+
- name: Build
|
|
26
|
+
run: python -m build
|
|
27
|
+
|
|
28
|
+
- name: Publish to PyPI
|
|
29
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
30
|
+
with:
|
|
31
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Python bytecode
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Test caches
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
.coverage
|
|
9
|
+
.coverage.*
|
|
10
|
+
htmlcov/
|
|
11
|
+
|
|
12
|
+
# Build / dist
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
.eggs/
|
|
17
|
+
|
|
18
|
+
# Virtual environments
|
|
19
|
+
.venv/
|
|
20
|
+
venv/
|
|
21
|
+
env/
|
|
22
|
+
|
|
23
|
+
# Editors
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
26
|
+
*.swp
|
|
27
|
+
.DS_Store
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eolas-data
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: Python client for the eolas.fyi statistical data API (NZ, Australia, OECD)
|
|
5
|
+
Project-URL: Homepage, https://eolas.fyi
|
|
6
|
+
Project-URL: Documentation, https://phildonovan.github.io/vswarehouse-docs/
|
|
7
|
+
Project-URL: Repository, https://github.com/phildonovan/eolas-data
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/phildonovan/eolas-data/issues
|
|
9
|
+
Author-email: Virtus Solutions <phil@virtus-solutions.io>
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: api,australia,economics,eolas,new-zealand,statistics
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: pandas>=1.5
|
|
24
|
+
Requires-Dist: requests>=2.28
|
|
25
|
+
Provides-Extra: cli
|
|
26
|
+
Requires-Dist: rich>=13; extra == 'cli'
|
|
27
|
+
Requires-Dist: typer>=0.12; extra == 'cli'
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: geopandas>=0.14; extra == 'dev'
|
|
30
|
+
Requires-Dist: pandas; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
32
|
+
Requires-Dist: responses; extra == 'dev'
|
|
33
|
+
Requires-Dist: rich>=13; extra == 'dev'
|
|
34
|
+
Requires-Dist: shapely>=2.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: typer>=0.12; extra == 'dev'
|
|
36
|
+
Provides-Extra: geo
|
|
37
|
+
Requires-Dist: geopandas>=0.14; extra == 'geo'
|
|
38
|
+
Requires-Dist: shapely>=2.0; extra == 'geo'
|
|
39
|
+
Provides-Extra: plot
|
|
40
|
+
Requires-Dist: matplotlib>=3.5; extra == 'plot'
|
|
41
|
+
Provides-Extra: polars
|
|
42
|
+
Requires-Dist: polars>=0.20; extra == 'polars'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# eolas-data
|
|
46
|
+
|
|
47
|
+
Python client for the [eolas.fyi](https://eolas.fyi) statistical data API — 717+ datasets across NZ, Australia, OECD, and more, served as tidy `pandas` DataFrames (or `polars` / `geopandas` if you prefer).
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install eolas-data
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from eolas_data import Client
|
|
57
|
+
|
|
58
|
+
client = Client("your_api_key") # or set EOLAS_API_KEY in env
|
|
59
|
+
|
|
60
|
+
# Generic
|
|
61
|
+
df = client.get("nz_cpi", start="2020-01-01")
|
|
62
|
+
|
|
63
|
+
# Source-specific (sets the `eolas_source` metadata)
|
|
64
|
+
df = client.statsnz("nz_cpi")
|
|
65
|
+
df = client.oecd("nz_gdp_production_annual")
|
|
66
|
+
|
|
67
|
+
# Discovery
|
|
68
|
+
all_datasets = client.list()
|
|
69
|
+
nz_only = client.list("Stats NZ")
|
|
70
|
+
meta = client.info("nz_cpi")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Get an API key at <https://eolas.fyi/signup>. Free plan is 10 requests/month; Starter is 100; Pro is unlimited.
|
|
74
|
+
|
|
75
|
+
## Command-line interface
|
|
76
|
+
|
|
77
|
+
`pip install eolas-data[cli]` adds an `eolas` command for browsing, fetching, and
|
|
78
|
+
scheduling — useful for shell scripts, cron jobs, and AI-agent workflows. Output
|
|
79
|
+
auto-detects piping: rich tables in a terminal, newline-delimited JSON when
|
|
80
|
+
stdout is piped.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# one-time setup
|
|
84
|
+
eolas auth set-key
|
|
85
|
+
eolas health
|
|
86
|
+
|
|
87
|
+
# discover
|
|
88
|
+
eolas datasets list --source "Stats NZ"
|
|
89
|
+
eolas datasets list --search cpi --json | jq '.[].name'
|
|
90
|
+
eolas datasets info nz_cpi
|
|
91
|
+
eolas datasets preview nz_cpi --limit 5
|
|
92
|
+
|
|
93
|
+
# fetch (verb matches the Python lib's client.get())
|
|
94
|
+
eolas get nz_cpi --format csv > cpi.csv
|
|
95
|
+
eolas get nz_cpi --start 2020-01-01 --format json | jq '.[].value'
|
|
96
|
+
eolas get sa2_2023 --format parquet --out sa2.parquet
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Scheduling
|
|
100
|
+
|
|
101
|
+
Set up recurring fetches without touching crontab/Task Scheduler syntax. Works
|
|
102
|
+
on Linux, macOS (cron), and Windows (Task Scheduler).
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
eolas schedule add nz_cpi --daily --out ~/data/cpi.csv
|
|
106
|
+
eolas schedule add nz_gdp --weekly --out ~/data/gdp.csv
|
|
107
|
+
eolas schedule add nzd_usd --cron "0 */6 * * *" --out ~/data/fx.csv # POSIX only
|
|
108
|
+
|
|
109
|
+
eolas schedule list
|
|
110
|
+
eolas schedule remove nz_cpi
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Daily is the default. Pre-flight check refuses to install a schedule unless
|
|
114
|
+
your API key is configured (otherwise the job would fail silently forever).
|
|
115
|
+
|
|
116
|
+
### Integrations (Enterprise plan)
|
|
117
|
+
|
|
118
|
+
Generate ready-to-run connector configs for popular data-pipeline tools — eolas
|
|
119
|
+
becomes a one-command source for Meltano, Fivetran, or Azure Data Factory.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
eolas integrate meltano --datasets nz_cpi,nz_gdp --output ./my-pipeline/
|
|
123
|
+
eolas integrate fivetran --datasets nz_cpi
|
|
124
|
+
eolas integrate azure-data-factory --datasets nz_cpi,nz_gdp
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The generated directory has everything needed to plug into your destination
|
|
128
|
+
warehouse: `meltano.yml`, `fivetran.yml`, or ADF JSON resources, plus a `README.md`
|
|
129
|
+
walking through the rest of the setup. Non-Enterprise users see a clear
|
|
130
|
+
upgrade pointer; the gating lives server-side so the capability is bypass-proof.
|
|
131
|
+
|
|
132
|
+
### Exit codes
|
|
133
|
+
|
|
134
|
+
Distinct exit codes per error class, for shell scripts and agents:
|
|
135
|
+
|
|
136
|
+
| Code | Meaning |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `0` | Success |
|
|
139
|
+
| `1` | Generic error |
|
|
140
|
+
| `2` | Auth (`AuthenticationError`, including Enterprise-gate 403) |
|
|
141
|
+
| `3` | Rate limit hit |
|
|
142
|
+
| `4` | Dataset / resource not found |
|
|
143
|
+
| `5` | Other API error |
|
|
144
|
+
| `64` | Bad usage (mirrors `sysexits.h`) |
|
|
145
|
+
|
|
146
|
+
## Geospatial
|
|
147
|
+
|
|
148
|
+
Datasets with a `geometry_wkt` column auto-convert to `geopandas.GeoDataFrame` if `geopandas` is installed:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pip install eolas-data[geo]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
gdf = client.get("nz_addresses") # GeoDataFrame
|
|
156
|
+
df = client.get("nz_addresses", as_geo=False) # plain DataFrame, WKT preserved
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Polars
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
pip install eolas-data[polars]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
df = client.get("nz_cpi", engine="polars")
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Plotting
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
pip install eolas-data[plot]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
df = client.statsnz("nz_cpi")
|
|
177
|
+
df.plot_dataset()
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Type stubs
|
|
181
|
+
|
|
182
|
+
Dataset names are exposed as a `Literal` so IDEs autocomplete the catalog:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from eolas_data import Client
|
|
186
|
+
|
|
187
|
+
client = Client()
|
|
188
|
+
client.get("nz_") # autocomplete shows nz_cpi, nz_gdp_production_annual, ...
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The list is regenerated from the live API at release time. Passing a name not in the snapshot still works at runtime — the type hint just won't autocomplete it. Catalog snapshot date is exposed as `eolas_data._dataset_names.CATALOG_SNAPSHOT_DATE`.
|
|
192
|
+
|
|
193
|
+
## Migrating from `vswarehouse`
|
|
194
|
+
|
|
195
|
+
The previous package name was `vswarehouse`. Direct equivalents:
|
|
196
|
+
|
|
197
|
+
| `vswarehouse` | `eolas_data` |
|
|
198
|
+
|---|---|
|
|
199
|
+
| `from vswarehouse import Client, VSeries` | `from eolas_data import Client, Dataset` |
|
|
200
|
+
| `df.vs_name`, `df.vs_source` | `df.eolas_name`, `df.eolas_source` |
|
|
201
|
+
| `df.plot_series()` | `df.plot_dataset()` |
|
|
202
|
+
| `VS_API_KEY` env var | `EOLAS_API_KEY` (legacy `VS_API_KEY` still honoured) |
|
|
203
|
+
|
|
204
|
+
The API surface is otherwise identical. The default base URL is now `https://api.eolas.fyi` (the old `https://api.virtus-solutions.io` still 301-redirects and works fine — but uses the legacy endpoint shape).
|
|
205
|
+
|
|
206
|
+
## Releasing
|
|
207
|
+
|
|
208
|
+
See [`docs/clients.md`](https://github.com/phildonovan/eolas/blob/master/docs/clients.md) in the eolas data repo for the tagged-release flow and PyPI token rotation.
|
|
209
|
+
|
|
210
|
+
Before each release: `python -m eolas_data._regen_names` to refresh the dataset name stubs from the live API, commit the change, then tag and push.
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
MIT
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# eolas-data
|
|
2
|
+
|
|
3
|
+
Python client for the [eolas.fyi](https://eolas.fyi) statistical data API — 717+ datasets across NZ, Australia, OECD, and more, served as tidy `pandas` DataFrames (or `polars` / `geopandas` if you prefer).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install eolas-data
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Quickstart
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from eolas_data import Client
|
|
13
|
+
|
|
14
|
+
client = Client("your_api_key") # or set EOLAS_API_KEY in env
|
|
15
|
+
|
|
16
|
+
# Generic
|
|
17
|
+
df = client.get("nz_cpi", start="2020-01-01")
|
|
18
|
+
|
|
19
|
+
# Source-specific (sets the `eolas_source` metadata)
|
|
20
|
+
df = client.statsnz("nz_cpi")
|
|
21
|
+
df = client.oecd("nz_gdp_production_annual")
|
|
22
|
+
|
|
23
|
+
# Discovery
|
|
24
|
+
all_datasets = client.list()
|
|
25
|
+
nz_only = client.list("Stats NZ")
|
|
26
|
+
meta = client.info("nz_cpi")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Get an API key at <https://eolas.fyi/signup>. Free plan is 10 requests/month; Starter is 100; Pro is unlimited.
|
|
30
|
+
|
|
31
|
+
## Command-line interface
|
|
32
|
+
|
|
33
|
+
`pip install eolas-data[cli]` adds an `eolas` command for browsing, fetching, and
|
|
34
|
+
scheduling — useful for shell scripts, cron jobs, and AI-agent workflows. Output
|
|
35
|
+
auto-detects piping: rich tables in a terminal, newline-delimited JSON when
|
|
36
|
+
stdout is piped.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# one-time setup
|
|
40
|
+
eolas auth set-key
|
|
41
|
+
eolas health
|
|
42
|
+
|
|
43
|
+
# discover
|
|
44
|
+
eolas datasets list --source "Stats NZ"
|
|
45
|
+
eolas datasets list --search cpi --json | jq '.[].name'
|
|
46
|
+
eolas datasets info nz_cpi
|
|
47
|
+
eolas datasets preview nz_cpi --limit 5
|
|
48
|
+
|
|
49
|
+
# fetch (verb matches the Python lib's client.get())
|
|
50
|
+
eolas get nz_cpi --format csv > cpi.csv
|
|
51
|
+
eolas get nz_cpi --start 2020-01-01 --format json | jq '.[].value'
|
|
52
|
+
eolas get sa2_2023 --format parquet --out sa2.parquet
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Scheduling
|
|
56
|
+
|
|
57
|
+
Set up recurring fetches without touching crontab/Task Scheduler syntax. Works
|
|
58
|
+
on Linux, macOS (cron), and Windows (Task Scheduler).
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
eolas schedule add nz_cpi --daily --out ~/data/cpi.csv
|
|
62
|
+
eolas schedule add nz_gdp --weekly --out ~/data/gdp.csv
|
|
63
|
+
eolas schedule add nzd_usd --cron "0 */6 * * *" --out ~/data/fx.csv # POSIX only
|
|
64
|
+
|
|
65
|
+
eolas schedule list
|
|
66
|
+
eolas schedule remove nz_cpi
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Daily is the default. Pre-flight check refuses to install a schedule unless
|
|
70
|
+
your API key is configured (otherwise the job would fail silently forever).
|
|
71
|
+
|
|
72
|
+
### Integrations (Enterprise plan)
|
|
73
|
+
|
|
74
|
+
Generate ready-to-run connector configs for popular data-pipeline tools — eolas
|
|
75
|
+
becomes a one-command source for Meltano, Fivetran, or Azure Data Factory.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
eolas integrate meltano --datasets nz_cpi,nz_gdp --output ./my-pipeline/
|
|
79
|
+
eolas integrate fivetran --datasets nz_cpi
|
|
80
|
+
eolas integrate azure-data-factory --datasets nz_cpi,nz_gdp
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The generated directory has everything needed to plug into your destination
|
|
84
|
+
warehouse: `meltano.yml`, `fivetran.yml`, or ADF JSON resources, plus a `README.md`
|
|
85
|
+
walking through the rest of the setup. Non-Enterprise users see a clear
|
|
86
|
+
upgrade pointer; the gating lives server-side so the capability is bypass-proof.
|
|
87
|
+
|
|
88
|
+
### Exit codes
|
|
89
|
+
|
|
90
|
+
Distinct exit codes per error class, for shell scripts and agents:
|
|
91
|
+
|
|
92
|
+
| Code | Meaning |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `0` | Success |
|
|
95
|
+
| `1` | Generic error |
|
|
96
|
+
| `2` | Auth (`AuthenticationError`, including Enterprise-gate 403) |
|
|
97
|
+
| `3` | Rate limit hit |
|
|
98
|
+
| `4` | Dataset / resource not found |
|
|
99
|
+
| `5` | Other API error |
|
|
100
|
+
| `64` | Bad usage (mirrors `sysexits.h`) |
|
|
101
|
+
|
|
102
|
+
## Geospatial
|
|
103
|
+
|
|
104
|
+
Datasets with a `geometry_wkt` column auto-convert to `geopandas.GeoDataFrame` if `geopandas` is installed:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pip install eolas-data[geo]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
gdf = client.get("nz_addresses") # GeoDataFrame
|
|
112
|
+
df = client.get("nz_addresses", as_geo=False) # plain DataFrame, WKT preserved
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Polars
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pip install eolas-data[polars]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
df = client.get("nz_cpi", engine="polars")
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Plotting
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
pip install eolas-data[plot]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
df = client.statsnz("nz_cpi")
|
|
133
|
+
df.plot_dataset()
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Type stubs
|
|
137
|
+
|
|
138
|
+
Dataset names are exposed as a `Literal` so IDEs autocomplete the catalog:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from eolas_data import Client
|
|
142
|
+
|
|
143
|
+
client = Client()
|
|
144
|
+
client.get("nz_") # autocomplete shows nz_cpi, nz_gdp_production_annual, ...
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The list is regenerated from the live API at release time. Passing a name not in the snapshot still works at runtime — the type hint just won't autocomplete it. Catalog snapshot date is exposed as `eolas_data._dataset_names.CATALOG_SNAPSHOT_DATE`.
|
|
148
|
+
|
|
149
|
+
## Migrating from `vswarehouse`
|
|
150
|
+
|
|
151
|
+
The previous package name was `vswarehouse`. Direct equivalents:
|
|
152
|
+
|
|
153
|
+
| `vswarehouse` | `eolas_data` |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `from vswarehouse import Client, VSeries` | `from eolas_data import Client, Dataset` |
|
|
156
|
+
| `df.vs_name`, `df.vs_source` | `df.eolas_name`, `df.eolas_source` |
|
|
157
|
+
| `df.plot_series()` | `df.plot_dataset()` |
|
|
158
|
+
| `VS_API_KEY` env var | `EOLAS_API_KEY` (legacy `VS_API_KEY` still honoured) |
|
|
159
|
+
|
|
160
|
+
The API surface is otherwise identical. The default base URL is now `https://api.eolas.fyi` (the old `https://api.virtus-solutions.io` still 301-redirects and works fine — but uses the legacy endpoint shape).
|
|
161
|
+
|
|
162
|
+
## Releasing
|
|
163
|
+
|
|
164
|
+
See [`docs/clients.md`](https://github.com/phildonovan/eolas/blob/master/docs/clients.md) in the eolas data repo for the tagged-release flow and PyPI token rotation.
|
|
165
|
+
|
|
166
|
+
Before each release: `python -m eolas_data._regen_names` to refresh the dataset name stubs from the live API, commit the change, then tag and push.
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""eolas-data — Python client for the eolas.fyi statistical data API."""
|
|
2
|
+
from .client import Client
|
|
3
|
+
from .dataset import Dataset
|
|
4
|
+
from .exceptions import APIError, AuthenticationError, EolasError, NotFoundError, RateLimitError
|
|
5
|
+
|
|
6
|
+
__version__ = "1.2.0"
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"Client",
|
|
10
|
+
"Dataset",
|
|
11
|
+
"EolasError",
|
|
12
|
+
"AuthenticationError",
|
|
13
|
+
"RateLimitError",
|
|
14
|
+
"NotFoundError",
|
|
15
|
+
"APIError",
|
|
16
|
+
]
|