gla-data 0.1.3__tar.gz → 0.2.2__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.
Files changed (49) hide show
  1. gla_data-0.2.2/.env.example +43 -0
  2. {gla_data-0.1.3 → gla_data-0.2.2}/.gitignore +3 -0
  3. {gla_data-0.1.3 → gla_data-0.2.2}/PKG-INFO +6 -10
  4. {gla_data-0.1.3 → gla_data-0.2.2}/README.md +3 -9
  5. gla_data-0.2.2/notebooks/addressbase_postgres_setup.ipynb +182 -0
  6. {gla_data-0.1.3 → gla_data-0.2.2}/pixi.lock +2575 -25
  7. {gla_data-0.1.3 → gla_data-0.2.2}/pixi.toml +4 -1
  8. {gla_data-0.1.3 → gla_data-0.2.2}/pyproject.toml +9 -2
  9. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/__init__.py +7 -1
  10. gla_data-0.2.2/src/gla_data/_lbsm.py +156 -0
  11. gla_data-0.2.2/src/gla_data/_londondatastore.py +91 -0
  12. gla_data-0.2.2/src/gla_data/_postgres.py +141 -0
  13. gla_data-0.2.2/src/gla_data/_schemas.py +367 -0
  14. gla_data-0.2.2/src/gla_data/addressbase.py +244 -0
  15. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/catalogue.py +18 -2
  16. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/cli.py +7 -2
  17. gla_data-0.2.2/src/gla_data/config.py +62 -0
  18. gla_data-0.2.2/src/gla_data/geography.py +321 -0
  19. gla_data-0.2.2/src/gla_data/lbsm.py +138 -0
  20. gla_data-0.2.2/tests/test_addressbase.py +362 -0
  21. gla_data-0.2.2/tests/test_boundaries.py +154 -0
  22. {gla_data-0.1.3 → gla_data-0.2.2}/tests/test_cli.py +2 -4
  23. gla_data-0.2.2/tests/test_gis_layer.py +77 -0
  24. gla_data-0.2.2/tests/test_lbsm.py +325 -0
  25. gla_data-0.2.2/tests/test_londondatastore.py +95 -0
  26. gla_data-0.2.2/tests/test_postgres.py +143 -0
  27. gla_data-0.1.3/.env.example +0 -11
  28. gla_data-0.1.3/src/gla_data/_schemas.py +0 -68
  29. gla_data-0.1.3/src/gla_data/config.py +0 -20
  30. gla_data-0.1.3/src/gla_data/geography.py +0 -156
  31. gla_data-0.1.3/tests/test_boundaries.py +0 -53
  32. {gla_data-0.1.3 → gla_data-0.2.2}/.copier-answers.yml +0 -0
  33. {gla_data-0.1.3 → gla_data-0.2.2}/.github/workflows/ci.yml +0 -0
  34. {gla_data-0.1.3 → gla_data-0.2.2}/.github/workflows/publish.yml +0 -0
  35. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/_arcgis.py +0 -0
  36. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/_cache.py +0 -0
  37. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/_ons.py +0 -0
  38. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/_ukds.py +0 -0
  39. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/census.py +0 -0
  40. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/py.typed +0 -0
  41. {gla_data-0.1.3 → gla_data-0.2.2}/src/gla_data/transforms.py +0 -0
  42. {gla_data-0.1.3 → gla_data-0.2.2}/tests/__init__.py +0 -0
  43. {gla_data-0.1.3 → gla_data-0.2.2}/tests/conftest.py +0 -0
  44. {gla_data-0.1.3 → gla_data-0.2.2}/tests/test_aggregate.py +0 -0
  45. {gla_data-0.1.3 → gla_data-0.2.2}/tests/test_catalogue.py +0 -0
  46. {gla_data-0.1.3 → gla_data-0.2.2}/tests/test_census_dwellings.py +0 -0
  47. {gla_data-0.1.3 → gla_data-0.2.2}/tests/test_crosswalk.py +0 -0
  48. {gla_data-0.1.3 → gla_data-0.2.2}/tests/test_geography_lookup.py +0 -0
  49. {gla_data-0.1.3 → gla_data-0.2.2}/uv.lock +0 -0
@@ -0,0 +1,43 @@
1
+ # Copy this file to .env and fill in values. Never commit .env.
2
+ # Settings are loaded from this file automatically by config.py.
3
+
4
+ # AWS (if used)
5
+ # AWS_DEFAULT_REGION=eu-west-2
6
+ # AWS_ACCESS_KEY_ID=
7
+ # AWS_SECRET_ACCESS_KEY=
8
+
9
+ # Application settings — override here for local development if needed.
10
+ # {{ import_name | upper }}_DATA_DIR=data
11
+ # {{ import_name | upper }}_OUTPUT_DIR=outputs
12
+
13
+ # --- GLA GIS team Postgres/PostGIS database (shared across many datasets) ---
14
+ # One shared connection is used for every dataset the GIS team hosts in Postgres.
15
+ GLA_DATA_GIS_DB_HOST=
16
+ GLA_DATA_GIS_DB_PORT=5432
17
+ GLA_DATA_GIS_DB_NAME=
18
+ GLA_DATA_GIS_DB_USER=
19
+ GLA_DATA_GIS_DB_PASSWORD=
20
+ # Optional: postgres schema (namespace) the tables live in. Leave blank for "public".
21
+ GLA_DATA_GIS_DB_SCHEMA=
22
+ # Table names for the BLPU and classification tables (defaults shown match
23
+ # AddressBase Premium's own GeoPackage layer names — override if different).
24
+ GLA_DATA_ADDRESSBASE_BLPU_TABLE=blpu
25
+ GLA_DATA_ADDRESSBASE_CLASSIFICATION_TABLE=classification
26
+
27
+ # GIS team "gisapdata" schema (within the same shared GIS DB above) — Highstreets,
28
+ # Town Centres, BIDs, CAZ, Boroughs, TfL Hexes, LSOA/MSOA 2011+2021, GLA boundary,
29
+ # London parks. Table names are GLA-internal — deliberately left blank here
30
+ # (not committed to git). Fill in your own .env with the real table names.
31
+ GLA_DATA_GISAPDATA_SCHEMA=gisapdata
32
+ GLA_DATA_GISAPDATA_BOROUGH_TABLE=
33
+ GLA_DATA_GISAPDATA_LSOA_2011_TABLE=
34
+ GLA_DATA_GISAPDATA_MSOA_2011_TABLE=
35
+ GLA_DATA_GISAPDATA_LSOA_2021_TABLE=
36
+ GLA_DATA_GISAPDATA_MSOA_2021_TABLE=
37
+ GLA_DATA_GISAPDATA_GLA_BOUNDARY_TABLE=
38
+ GLA_DATA_GISAPDATA_HIGH_STREETS_TABLE=
39
+ GLA_DATA_GISAPDATA_TOWN_CENTRES_TABLE=
40
+ GLA_DATA_GISAPDATA_BIDS_TABLE=
41
+ GLA_DATA_GISAPDATA_CAZ_TABLE=
42
+ GLA_DATA_GISAPDATA_TFL_HEX_TABLE=
43
+ GLA_DATA_GISAPDATA_PARKS_TABLE=
@@ -22,6 +22,9 @@ htmlcov/
22
22
  .idea/
23
23
  *.swp
24
24
 
25
+ # Jupyter
26
+ .ipynb_checkpoints/
27
+
25
28
  # Secrets
26
29
  .env
27
30
 
@@ -1,16 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gla-data
3
- Version: 0.1.3
3
+ Version: 0.2.2
4
4
  Summary: Shared tools for loading, transforming, and visualising the GLA datasets used in City Data analysis.
5
5
  Author-email: Conor Dempsey <conor.dempsey@london.gov.uk>
6
6
  License: MIT
7
7
  Requires-Python: >=3.12
8
+ Requires-Dist: beautifulsoup4>=4.12
8
9
  Requires-Dist: geopandas>=1.0
9
10
  Requires-Dist: pandas>=2.2
10
11
  Requires-Dist: pandera>=0.32.1
11
12
  Requires-Dist: pyarrow>=24.0.0
12
13
  Requires-Dist: pydantic-settings
13
14
  Requires-Dist: requests>=2.32
15
+ Requires-Dist: sqlalchemy>=2.0
14
16
  Requires-Dist: typer>=0.26.8
15
17
  Description-Content-Type: text/markdown
16
18
 
@@ -20,21 +22,15 @@ Shared tools for loading, transforming, and visualising the GLA datasets used in
20
22
 
21
23
  ## Installation
22
24
 
23
- ### Global install (CLI)
25
+ ### CLI
24
26
 
25
- To install `gla-data` globally so the `gla-data` CLI is available anywhere in your terminal, use `uv tool`:
27
+ To install `gla-data` globally so the `gla-data` CLI is available anywhere in your terminal:
26
28
 
27
29
  ```bash
28
30
  uv tool install gla-data
29
31
  ```
30
32
 
31
- Normally `pixi global install` would be the preferred approach, but it does not yet support PyPI packages — so `uv tool` is the right choice for now.
32
-
33
- If you don't have `uv` installed, you can install it via pixi:
34
-
35
- ```bash
36
- pixi global install uv
37
- ```
33
+ This requires [uv](https://docs.astral.sh/uv/) to be installed.
38
34
 
39
35
  ### pip
40
36
 
@@ -4,21 +4,15 @@ Shared tools for loading, transforming, and visualising the GLA datasets used in
4
4
 
5
5
  ## Installation
6
6
 
7
- ### Global install (CLI)
7
+ ### CLI
8
8
 
9
- To install `gla-data` globally so the `gla-data` CLI is available anywhere in your terminal, use `uv tool`:
9
+ To install `gla-data` globally so the `gla-data` CLI is available anywhere in your terminal:
10
10
 
11
11
  ```bash
12
12
  uv tool install gla-data
13
13
  ```
14
14
 
15
- Normally `pixi global install` would be the preferred approach, but it does not yet support PyPI packages — so `uv tool` is the right choice for now.
16
-
17
- If you don't have `uv` installed, you can install it via pixi:
18
-
19
- ```bash
20
- pixi global install uv
21
- ```
15
+ This requires [uv](https://docs.astral.sh/uv/) to be installed.
22
16
 
23
17
  ### pip
24
18
 
@@ -0,0 +1,182 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "cell-00",
6
+ "metadata": {},
7
+ "source": [
8
+ "# AddressBase Premium \u2014 Postgres connection setup & schema reflection\n",
9
+ "\n",
10
+ "Run this once you've populated `.env` with the `GLA_DATA_GIS_DB_*` variables (see `.env.example` in the repo root).\n",
11
+ "\n",
12
+ "This notebook does three things, in order:\n",
13
+ "\n",
14
+ "1. **Connect and reflect** the real table/column schema directly from the database \u2014 a one-off discovery step, since the exact table/column names in this database haven't been confirmed yet.\n",
15
+ "2. **Export** the reflected schema to a file, so it can be read in a follow-up task to write a proper pandera schema in code (rather than guessing column names).\n",
16
+ "3. **Sanity-check** `gla_data.load_addressbase(source='postgres')` against the real data.\n",
17
+ "\n",
18
+ "Nothing here is destructive \u2014 every step is a read-only query."
19
+ ]
20
+ },
21
+ {
22
+ "cell_type": "code",
23
+ "execution_count": null,
24
+ "id": "cell-01",
25
+ "metadata": {},
26
+ "outputs": [],
27
+ "source": [
28
+ "import gla_data\n",
29
+ "from gla_data import _postgres\n",
30
+ "from gla_data.config import settings\n",
31
+ "\n",
32
+ "print(\"Configured settings (password hidden):\")\n",
33
+ "print(f\" host: {settings.gis_db_host}\")\n",
34
+ "print(f\" port: {settings.gis_db_port}\")\n",
35
+ "print(f\" dbname: {settings.gis_db_name}\")\n",
36
+ "print(f\" user: {settings.gis_db_user}\")\n",
37
+ "print(f\" schema: {settings.gis_db_schema or '(default search path)'}\")\n",
38
+ "\n",
39
+ "if not settings.gis_db_host:\n",
40
+ " raise RuntimeError(\n",
41
+ " \"GLA_DATA_GIS_DB_* settings not found \u2014 check your \"\n",
42
+ " \".env file is in the working directory this notebook runs from, \"\n",
43
+ " \"and matches .env.example's variable names.\"\n",
44
+ " )"
45
+ ]
46
+ },
47
+ {
48
+ "cell_type": "markdown",
49
+ "id": "cell-02",
50
+ "metadata": {},
51
+ "source": [
52
+ "## 1. Connect and reflect the schema\n",
53
+ "\n",
54
+ "Lists every table and column gla_data's configured database user can see."
55
+ ]
56
+ },
57
+ {
58
+ "cell_type": "code",
59
+ "execution_count": null,
60
+ "id": "cell-03",
61
+ "metadata": {},
62
+ "outputs": [],
63
+ "source": [
64
+ "engine = _postgres.get_engine()\n",
65
+ "schema_df = _postgres.reflect_schema(engine, schema=settings.gis_db_schema)\n",
66
+ "\n",
67
+ "print(f\"{schema_df['table_name'].nunique()} tables, {len(schema_df)} columns total\")\n",
68
+ "schema_df"
69
+ ]
70
+ },
71
+ {
72
+ "cell_type": "markdown",
73
+ "id": "cell-04",
74
+ "metadata": {},
75
+ "source": [
76
+ "### Tables of interest\n",
77
+ "\n",
78
+ "Filtered to the two tables `compute_uprn_net_change` expects (BLPU-equivalent + classification-equivalent), using the configured table names as a starting guess. **Look at the full table list above first** \u2014 if the real tables are named differently, update `GLA_DATA_ADDRESSBASE_BLPU_TABLE` / `GLA_DATA_ADDRESSBASE_CLASSIFICATION_TABLE` in `.env` (or just change `tables_of_interest` below for this exploratory pass)."
79
+ ]
80
+ },
81
+ {
82
+ "cell_type": "code",
83
+ "execution_count": null,
84
+ "id": "cell-05",
85
+ "metadata": {},
86
+ "outputs": [],
87
+ "source": [
88
+ "tables_of_interest = [\n",
89
+ " settings.addressbase_blpu_table,\n",
90
+ " settings.addressbase_classification_table,\n",
91
+ "]\n",
92
+ "schema_df[schema_df[\"table_name\"].isin(tables_of_interest)]"
93
+ ]
94
+ },
95
+ {
96
+ "cell_type": "markdown",
97
+ "id": "cell-06",
98
+ "metadata": {},
99
+ "source": [
100
+ "## 2. Export the reflected schema\n",
101
+ "\n",
102
+ "Saved next to this notebook. This file is what gets read in the next task to write `compute_uprn_net_change`'s real pandera input schema \u2014 don't rename it without updating that task."
103
+ ]
104
+ },
105
+ {
106
+ "cell_type": "code",
107
+ "execution_count": null,
108
+ "id": "cell-07",
109
+ "metadata": {},
110
+ "outputs": [],
111
+ "source": [
112
+ "from pathlib import Path\n",
113
+ "\n",
114
+ "export_path = Path(\"addressbase_schema_reflection.json\")\n",
115
+ "schema_df.to_json(export_path, orient=\"records\", indent=2)\n",
116
+ "print(f\"Exported {len(schema_df)} rows to {export_path.resolve()}\")"
117
+ ]
118
+ },
119
+ {
120
+ "cell_type": "markdown",
121
+ "id": "cell-08",
122
+ "metadata": {},
123
+ "source": [
124
+ "## 3. Sanity-check `load_addressbase`\n",
125
+ "\n",
126
+ "Reads the configured BLPU table as-is (no column mapping yet \u2014 see the function's docstring). Confirms the connection, driver, and geometry handling all work end-to-end against the real database, independent of the schema-reflection step above."
127
+ ]
128
+ },
129
+ {
130
+ "cell_type": "code",
131
+ "execution_count": null,
132
+ "id": "cell-09",
133
+ "metadata": {},
134
+ "outputs": [],
135
+ "source": [
136
+ "raw = gla_data.load_addressbase(source=\"postgres\")\n",
137
+ "print(type(raw))\n",
138
+ "print(f\"{len(raw)} rows\")\n",
139
+ "print(f\"columns: {list(raw.columns)}\")\n",
140
+ "raw.head()"
141
+ ]
142
+ },
143
+ {
144
+ "cell_type": "markdown",
145
+ "id": "cell-10",
146
+ "metadata": {},
147
+ "source": [
148
+ "### Optional: the classification table\n",
149
+ "\n",
150
+ "Same check against the second table `compute_uprn_net_change` will eventually need (the residential-classification filter)."
151
+ ]
152
+ },
153
+ {
154
+ "cell_type": "code",
155
+ "execution_count": null,
156
+ "id": "cell-11",
157
+ "metadata": {},
158
+ "outputs": [],
159
+ "source": [
160
+ "classification_raw = gla_data.load_addressbase(\n",
161
+ " source=\"postgres\", table=settings.addressbase_classification_table\n",
162
+ ")\n",
163
+ "print(f\"{len(classification_raw)} rows\")\n",
164
+ "print(f\"columns: {list(classification_raw.columns)}\")\n",
165
+ "classification_raw.head()"
166
+ ]
167
+ }
168
+ ],
169
+ "metadata": {
170
+ "kernelspec": {
171
+ "display_name": "Python 3 (gla-data)",
172
+ "language": "python",
173
+ "name": "python3"
174
+ },
175
+ "language_info": {
176
+ "name": "python",
177
+ "version": "3.12"
178
+ }
179
+ },
180
+ "nbformat": 4,
181
+ "nbformat_minor": 5
182
+ }