eolas-data 1.2.0__tar.gz → 1.3.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.
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eolas-data
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Python client for the eolas.fyi statistical data API (NZ, Australia, OECD)
5
5
  Project-URL: Homepage, https://eolas.fyi
6
- Project-URL: Documentation, https://phildonovan.github.io/vswarehouse-docs/
6
+ Project-URL: Documentation, https://docs.eolas.fyi/
7
7
  Project-URL: Repository, https://github.com/phildonovan/eolas-data
8
8
  Project-URL: Bug Tracker, https://github.com/phildonovan/eolas-data/issues
9
9
  Author-email: Virtus Solutions <phil@virtus-solutions.io>
@@ -36,8 +36,6 @@ Requires-Dist: typer>=0.12; extra == 'dev'
36
36
  Provides-Extra: geo
37
37
  Requires-Dist: geopandas>=0.14; extra == 'geo'
38
38
  Requires-Dist: shapely>=2.0; extra == 'geo'
39
- Provides-Extra: plot
40
- Requires-Dist: matplotlib>=3.5; extra == 'plot'
41
39
  Provides-Extra: polars
42
40
  Requires-Dist: polars>=0.20; extra == 'polars'
43
41
  Description-Content-Type: text/markdown
@@ -168,13 +166,17 @@ df = client.get("nz_cpi", engine="polars")
168
166
 
169
167
  ## Plotting
170
168
 
171
- ```bash
172
- pip install eolas-data[plot]
173
- ```
169
+ `Dataset` is a `pandas.DataFrame` subclass — use matplotlib / seaborn / plotly
170
+ directly. No bundled plot helper, because there's no universal "right" plot for
171
+ a tidy dataset (single-series time series vs. wide multi-measure vs. WKT
172
+ geometry all need different code).
174
173
 
175
174
  ```python
175
+ import matplotlib.pyplot as plt
176
+
176
177
  df = client.statsnz("nz_cpi")
177
- df.plot_dataset()
178
+ df.plot(x="date", y="value")
179
+ plt.show()
178
180
  ```
179
181
 
180
182
  ## Type stubs
@@ -198,7 +200,7 @@ The previous package name was `vswarehouse`. Direct equivalents:
198
200
  |---|---|
199
201
  | `from vswarehouse import Client, VSeries` | `from eolas_data import Client, Dataset` |
200
202
  | `df.vs_name`, `df.vs_source` | `df.eolas_name`, `df.eolas_source` |
201
- | `df.plot_series()` | `df.plot_dataset()` |
203
+ | `df.plot_series()` | *(removed in v1.3.0 — use `df.plot(x="date", y="value")` directly; the helper silently mis-rendered datasets with multi-row dates)* |
202
204
  | `VS_API_KEY` env var | `EOLAS_API_KEY` (legacy `VS_API_KEY` still honoured) |
203
205
 
204
206
  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).
@@ -124,13 +124,17 @@ df = client.get("nz_cpi", engine="polars")
124
124
 
125
125
  ## Plotting
126
126
 
127
- ```bash
128
- pip install eolas-data[plot]
129
- ```
127
+ `Dataset` is a `pandas.DataFrame` subclass — use matplotlib / seaborn / plotly
128
+ directly. No bundled plot helper, because there's no universal "right" plot for
129
+ a tidy dataset (single-series time series vs. wide multi-measure vs. WKT
130
+ geometry all need different code).
130
131
 
131
132
  ```python
133
+ import matplotlib.pyplot as plt
134
+
132
135
  df = client.statsnz("nz_cpi")
133
- df.plot_dataset()
136
+ df.plot(x="date", y="value")
137
+ plt.show()
134
138
  ```
135
139
 
136
140
  ## Type stubs
@@ -154,7 +158,7 @@ The previous package name was `vswarehouse`. Direct equivalents:
154
158
  |---|---|
155
159
  | `from vswarehouse import Client, VSeries` | `from eolas_data import Client, Dataset` |
156
160
  | `df.vs_name`, `df.vs_source` | `df.eolas_name`, `df.eolas_source` |
157
- | `df.plot_series()` | `df.plot_dataset()` |
161
+ | `df.plot_series()` | *(removed in v1.3.0 — use `df.plot(x="date", y="value")` directly; the helper silently mis-rendered datasets with multi-row dates)* |
158
162
  | `VS_API_KEY` env var | `EOLAS_API_KEY` (legacy `VS_API_KEY` still honoured) |
159
163
 
160
164
  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).
@@ -580,7 +580,7 @@ def integrate_meltano(
580
580
  json_out: bool = typer.Option(False, "--json"),
581
581
  api_key: Optional[str] = typer.Option(None, "--api-key"),
582
582
  ) -> None:
583
- """Generate a Meltano project (uses `tap-rest-api-msdk`) for the chosen datasets."""
583
+ """[verified] Generate a Meltano project (uses `tap-rest-api-msdk`) for the chosen datasets."""
584
584
  _run_integration("meltano", datasets, output or _default_output_dir("meltano"),
585
585
  force, api_key, json_out)
586
586
 
@@ -593,9 +593,20 @@ def integrate_fivetran(
593
593
  json_out: bool = typer.Option(False, "--json"),
594
594
  api_key: Optional[str] = typer.Option(None, "--api-key"),
595
595
  ) -> None:
596
- """Generate a Fivetran Connector Builder YAML for the chosen datasets."""
596
+ """[experimental] Generate a Fivetran Connector Builder YAML for the chosen datasets.
597
+
598
+ Output is structure-verified (parses as YAML, has all the fields the spec
599
+ documents) but has not yet been end-to-end tested against a real Fivetran
600
+ Connector Builder import. If the import rejects with a schema error,
601
+ please share the error so the generator can be fixed.
602
+ """
597
603
  _run_integration("fivetran", datasets, output or _default_output_dir("fivetran"),
598
604
  force, api_key, json_out)
605
+ if not _machine_mode(json_out):
606
+ err_console.print(
607
+ "[yellow]experimental:[/yellow] Fivetran output is structure-verified "
608
+ "but not yet end-to-end tested against a real account."
609
+ )
599
610
 
600
611
 
601
612
  @integrate_app.command("azure-data-factory")
@@ -606,10 +617,21 @@ def integrate_adf(
606
617
  json_out: bool = typer.Option(False, "--json"),
607
618
  api_key: Optional[str] = typer.Option(None, "--api-key"),
608
619
  ) -> None:
609
- """Generate Azure Data Factory linked-service / dataset / pipeline JSON."""
620
+ """[experimental] Generate Azure Data Factory linked-service / dataset / pipeline JSON.
621
+
622
+ Output is structure-verified (linked-service references resolve, datasets
623
+ reference real linked services, pipeline activities reference real
624
+ datasets) but has not yet been end-to-end tested against a real Azure
625
+ subscription.
626
+ """
610
627
  _run_integration("azure-data-factory", datasets,
611
628
  output or _default_output_dir("adf"),
612
629
  force, api_key, json_out)
630
+ if not _machine_mode(json_out):
631
+ err_console.print(
632
+ "[yellow]experimental:[/yellow] Azure Data Factory output is "
633
+ "structure-verified but not yet end-to-end tested against a real subscription."
634
+ )
613
635
 
614
636
 
615
637
  # Allow `python -m eolas_data.cli`
@@ -166,8 +166,14 @@ class Client:
166
166
  return self._get_source(name, "LINZ", **kwargs)
167
167
 
168
168
  def statsnz_geo(self, name, **kwargs) -> Dataset:
169
- """Fetch a Stats NZ Geospatial dataset."""
170
- return self._get_source(name, "Stats NZ Geospatial", **kwargs)
169
+ """Fetch a Stats NZ geospatial dataset (boundaries, census meshblocks, etc.).
170
+
171
+ Kept as a convenience helper for discoverability — the server returns
172
+ ``source = "Stats NZ"`` for both SDMX time series and Datafinder
173
+ geospatial datasets, so the metadata on the returned Dataset reads
174
+ ``"Stats NZ"`` (not ``"Stats NZ Geospatial"``).
175
+ """
176
+ return self._get_source(name, "Stats NZ", **kwargs)
171
177
 
172
178
  def mbie(self, name, **kwargs) -> Dataset:
173
179
  """Fetch an MBIE dataset."""
@@ -0,0 +1,46 @@
1
+ from __future__ import annotations
2
+
3
+ import pandas as pd
4
+
5
+
6
+ class Dataset(pd.DataFrame):
7
+ """A pandas DataFrame with eolas dataset metadata.
8
+
9
+ Behaves exactly like a DataFrame — all pandas operations work normally.
10
+ Extra attributes:
11
+ eolas_name: Dataset identifier (e.g. ``"nz_cpi"``).
12
+ eolas_source: Data source label (e.g. ``"Stats NZ"``).
13
+ """
14
+
15
+ _metadata = ["eolas_name", "eolas_source"]
16
+
17
+ @property
18
+ def _constructor(self):
19
+ return Dataset
20
+
21
+ def __repr__(self) -> str:
22
+ name = getattr(self, "eolas_name", "") or ""
23
+ source = getattr(self, "eolas_source", "") or ""
24
+ if name:
25
+ header = f"# Dataset: {name}"
26
+ if source:
27
+ header += f" [{source}]"
28
+ header += f"\n# {len(self)} rows\n"
29
+ return header + pd.DataFrame.__repr__(self)
30
+ return pd.DataFrame.__repr__(self)
31
+
32
+ # ------------------------------------------------------------------
33
+ # plot_dataset() was removed in v1.3.0.
34
+ #
35
+ # It auto-picked `date` and `value` columns and drew a single matplotlib
36
+ # line — but datasets with a dimension column (multiple series per date)
37
+ # produced silent zigzag traces. Rather than ship a helper that has to
38
+ # know each dataset's shape, plotting is now the caller's responsibility.
39
+ # `Dataset` subclasses `DataFrame`, so any matplotlib / seaborn / plotly
40
+ # workflow works straight out of the box:
41
+ #
42
+ # import matplotlib.pyplot as plt
43
+ # df.plot(x="date", y="value")
44
+ #
45
+ # See README for one-liners.
46
+ # ------------------------------------------------------------------
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "eolas-data"
7
- version = "1.2.0"
7
+ version = "1.3.0"
8
8
  description = "Python client for the eolas.fyi statistical data API (NZ, Australia, OECD)"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -30,14 +30,13 @@ classifiers = [
30
30
 
31
31
  [project.urls]
32
32
  Homepage = "https://eolas.fyi"
33
- Documentation = "https://phildonovan.github.io/vswarehouse-docs/"
33
+ Documentation = "https://docs.eolas.fyi/"
34
34
  Repository = "https://github.com/phildonovan/eolas-data"
35
35
  "Bug Tracker" = "https://github.com/phildonovan/eolas-data/issues"
36
36
 
37
37
  [project.optional-dependencies]
38
38
  dev = ["pytest", "responses", "pandas", "geopandas>=0.14", "shapely>=2.0", "typer>=0.12", "rich>=13"]
39
39
  polars = ["polars>=0.20"]
40
- plot = ["matplotlib>=3.5"]
41
40
  geo = ["geopandas>=0.14", "shapely>=2.0"]
42
41
  cli = ["typer>=0.12", "rich>=13"]
43
42
 
@@ -1,66 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import pandas as pd
4
-
5
-
6
- class Dataset(pd.DataFrame):
7
- """A pandas DataFrame with eolas dataset metadata.
8
-
9
- Behaves exactly like a DataFrame — all pandas operations work normally.
10
- Extra attributes:
11
- eolas_name: Dataset identifier (e.g. ``"nz_cpi"``).
12
- eolas_source: Data source label (e.g. ``"Stats NZ"``).
13
- """
14
-
15
- _metadata = ["eolas_name", "eolas_source"]
16
-
17
- @property
18
- def _constructor(self):
19
- return Dataset
20
-
21
- def __repr__(self) -> str:
22
- name = getattr(self, "eolas_name", "") or ""
23
- source = getattr(self, "eolas_source", "") or ""
24
- if name:
25
- header = f"# Dataset: {name}"
26
- if source:
27
- header += f" [{source}]"
28
- header += f"\n# {len(self)} rows\n"
29
- return header + pd.DataFrame.__repr__(self)
30
- return pd.DataFrame.__repr__(self)
31
-
32
- def plot_dataset(self, ax=None, **kwargs):
33
- """Quick line chart using matplotlib.
34
-
35
- Returns the matplotlib Axes object so you can customise further.
36
- Requires matplotlib: ``pip install eolas-data[plot]``.
37
- """
38
- try:
39
- import matplotlib.pyplot as plt
40
- except ImportError:
41
- raise ImportError(
42
- "matplotlib is required for plot_dataset(). "
43
- "Install with: pip install eolas-data[plot]"
44
- )
45
-
46
- date_col = "date" if "date" in self.columns else self.columns[0]
47
- value_col = "value" if "value" in self.columns else self.columns[1]
48
-
49
- if ax is None:
50
- _, ax = plt.subplots(figsize=(10, 4))
51
-
52
- ax.plot(self[date_col], self[value_col], color="#2563eb", linewidth=1.5, **kwargs)
53
-
54
- name = getattr(self, "eolas_name", "") or ""
55
- source = getattr(self, "eolas_source", "") or ""
56
-
57
- if name:
58
- ax.set_title(name, fontweight="bold", fontsize=13)
59
- ax.set_xlabel("")
60
- ax.spines[["top", "right"]].set_visible(False)
61
-
62
- caption = f"Source: {source} · eolas.fyi" if source else "eolas.fyi"
63
- ax.figure.text(0.99, 0.01, caption, ha="right", fontsize=8, color="#9ca3af")
64
-
65
- plt.tight_layout()
66
- return ax
File without changes
File without changes