pycancensus 0.1.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.
- pycancensus-0.1.0/LICENSE +21 -0
- pycancensus-0.1.0/MANIFEST.in +62 -0
- pycancensus-0.1.0/PKG-INFO +268 -0
- pycancensus-0.1.0/README.md +217 -0
- pycancensus-0.1.0/examples/basic_usage.py +142 -0
- pycancensus-0.1.0/examples/getting_started.ipynb +722 -0
- pycancensus-0.1.0/pycancensus/__init__.py +52 -0
- pycancensus-0.1.0/pycancensus/cache.py +187 -0
- pycancensus-0.1.0/pycancensus/cli.py +184 -0
- pycancensus-0.1.0/pycancensus/core.py +512 -0
- pycancensus-0.1.0/pycancensus/datasets.py +217 -0
- pycancensus-0.1.0/pycancensus/geometry.py +67 -0
- pycancensus-0.1.0/pycancensus/hierarchy.py +362 -0
- pycancensus-0.1.0/pycancensus/intersect_geometry.py +218 -0
- pycancensus-0.1.0/pycancensus/progress.py +247 -0
- pycancensus-0.1.0/pycancensus/regions.py +171 -0
- pycancensus-0.1.0/pycancensus/resilience.py +334 -0
- pycancensus-0.1.0/pycancensus/settings.py +221 -0
- pycancensus-0.1.0/pycancensus/utils.py +151 -0
- pycancensus-0.1.0/pycancensus/vectors.py +296 -0
- pycancensus-0.1.0/pycancensus.egg-info/SOURCES.txt +23 -0
- pycancensus-0.1.0/pyproject.toml +121 -0
- pycancensus-0.1.0/requirements-dev.txt +21 -0
- pycancensus-0.1.0/requirements.txt +3 -0
- pycancensus-0.1.0/setup.cfg +4 -0
- pycancensus-0.1.0/setup.py +23 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Dmitry Shkolnik, Jens von Bergmann, Aaron Jacobs
|
|
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,62 @@
|
|
|
1
|
+
# MANIFEST.in - Controls what gets included in source distributions
|
|
2
|
+
# This is Python's equivalent to R's .Rbuildignore
|
|
3
|
+
|
|
4
|
+
# Include documentation and essential files
|
|
5
|
+
include README.md
|
|
6
|
+
include LICENSE
|
|
7
|
+
include requirements.txt
|
|
8
|
+
include requirements-dev.txt
|
|
9
|
+
|
|
10
|
+
# Include package data
|
|
11
|
+
recursive-include pycancensus *.py
|
|
12
|
+
recursive-include pycancensus *.json
|
|
13
|
+
recursive-include pycancensus *.yaml
|
|
14
|
+
|
|
15
|
+
# Include examples (but not test notebooks)
|
|
16
|
+
recursive-include examples *.py
|
|
17
|
+
include examples/getting_started.ipynb
|
|
18
|
+
include examples/basic_usage.py
|
|
19
|
+
|
|
20
|
+
# Exclude all test directories from source distributions
|
|
21
|
+
prune tests
|
|
22
|
+
prune test
|
|
23
|
+
prune testing
|
|
24
|
+
|
|
25
|
+
# Exclude development and debugging files
|
|
26
|
+
exclude debug_*.py
|
|
27
|
+
exclude debug_*.R
|
|
28
|
+
exclude notebook_debug.py
|
|
29
|
+
exclude test_demographic_workflow.py
|
|
30
|
+
|
|
31
|
+
# Exclude build artifacts
|
|
32
|
+
prune build
|
|
33
|
+
prune dist
|
|
34
|
+
prune *.egg-info
|
|
35
|
+
prune __pycache__
|
|
36
|
+
global-exclude *.pyc
|
|
37
|
+
global-exclude *.pyo
|
|
38
|
+
global-exclude *.pyd
|
|
39
|
+
global-exclude .DS_Store
|
|
40
|
+
global-exclude *.so
|
|
41
|
+
|
|
42
|
+
# Exclude version control and CI files
|
|
43
|
+
exclude .gitignore
|
|
44
|
+
exclude .github
|
|
45
|
+
prune .github
|
|
46
|
+
|
|
47
|
+
# Exclude IDE and editor files
|
|
48
|
+
exclude .vscode
|
|
49
|
+
exclude .idea
|
|
50
|
+
prune .vscode
|
|
51
|
+
prune .idea
|
|
52
|
+
global-exclude *.swp
|
|
53
|
+
global-exclude *.swo
|
|
54
|
+
global-exclude *~
|
|
55
|
+
|
|
56
|
+
# Exclude cross-validation and analysis files
|
|
57
|
+
exclude tests/cross_validation
|
|
58
|
+
prune tests/cross_validation
|
|
59
|
+
|
|
60
|
+
# Exclude Jupyter notebook checkpoints
|
|
61
|
+
prune .ipynb_checkpoints
|
|
62
|
+
global-exclude .ipynb_checkpoints
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pycancensus
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Access, retrieve, and work with Canadian Census data and geography
|
|
5
|
+
Author-email: Dmitry Shkolnik <shkolnikd@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dshkol/pycancensus
|
|
8
|
+
Project-URL: Repository, https://github.com/dshkol/pycancensus
|
|
9
|
+
Project-URL: Documentation, https://pycancensus.readthedocs.io
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/dshkol/pycancensus/issues
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
23
|
+
Requires-Python: >=3.7
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: requests>=2.25.0
|
|
27
|
+
Requires-Dist: pandas>=1.0.0
|
|
28
|
+
Requires-Dist: geopandas>=0.8.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
32
|
+
Requires-Dist: black; extra == "dev"
|
|
33
|
+
Requires-Dist: flake8; extra == "dev"
|
|
34
|
+
Provides-Extra: docs
|
|
35
|
+
Requires-Dist: sphinx>=4.0; extra == "docs"
|
|
36
|
+
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
|
37
|
+
Requires-Dist: myst-nb>=0.17; extra == "docs"
|
|
38
|
+
Requires-Dist: sphinx-gallery>=0.11; extra == "docs"
|
|
39
|
+
Requires-Dist: sphinx-autosummary-accessors; extra == "docs"
|
|
40
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
41
|
+
Requires-Dist: matplotlib>=3.4.0; extra == "docs"
|
|
42
|
+
Requires-Dist: folium>=0.12.0; extra == "docs"
|
|
43
|
+
Provides-Extra: cross-validation
|
|
44
|
+
Requires-Dist: rpy2>=3.4.0; extra == "cross-validation"
|
|
45
|
+
Requires-Dist: tqdm>=4.62.0; extra == "cross-validation"
|
|
46
|
+
Requires-Dist: deepdiff>=5.6.0; extra == "cross-validation"
|
|
47
|
+
Requires-Dist: tabulate>=0.8.9; extra == "cross-validation"
|
|
48
|
+
Requires-Dist: matplotlib>=3.4.0; extra == "cross-validation"
|
|
49
|
+
Requires-Dist: seaborn>=0.11.0; extra == "cross-validation"
|
|
50
|
+
Dynamic: license-file
|
|
51
|
+
|
|
52
|
+
# pycancensus
|
|
53
|
+
|
|
54
|
+
[](https://opensource.org/licenses/MIT)
|
|
55
|
+
[](https://www.python.org/downloads/)
|
|
56
|
+
[](https://pycancensus.readthedocs.io/en/latest/?badge=latest)
|
|
57
|
+
[](tests/)
|
|
58
|
+
[](tests/cross_validation/)
|
|
59
|
+
|
|
60
|
+
Access, retrieve, and work with Canadian Census data and geography.
|
|
61
|
+
|
|
62
|
+
**pycancensus** is a Python package that provides integrated, convenient, and uniform access to Canadian Census data and geography retrieved using the CensusMapper API. This package produces analysis-ready tidy DataFrames and spatial data in multiple formats, with full equivalence to the R cancensus library.
|
|
63
|
+
|
|
64
|
+
## Recent Updates
|
|
65
|
+
|
|
66
|
+
- **Full R Library Equivalence**: Verified 100% data compatibility with R cancensus
|
|
67
|
+
- **Enhanced API Reliability**: Production-grade error handling and retry logic
|
|
68
|
+
- **Vector Hierarchy Functions**: Navigate census variable relationships like R
|
|
69
|
+
- **Improved Data Quality**: Fixed column naming and data processing issues
|
|
70
|
+
- **Comprehensive Testing**: 450+ integration tests covering real-world scenarios
|
|
71
|
+
- **National-Level Support**: Added level='C' for Canada-wide baseline comparisons
|
|
72
|
+
|
|
73
|
+
## Features
|
|
74
|
+
|
|
75
|
+
### Data Access
|
|
76
|
+
* Download Census data and geography in analysis-ready format
|
|
77
|
+
* Support for multiple Census years: 2021, 2016, 2011, 2006, 2001, 1996
|
|
78
|
+
* All Census geographic levels: PR, CMA, CD, CSD, CT, DA, EA, DB
|
|
79
|
+
* Taxfiler data at Census Tract level (2000-2018)
|
|
80
|
+
|
|
81
|
+
### Variable Discovery
|
|
82
|
+
* `list_census_vectors()` - Browse all available variables
|
|
83
|
+
* `search_census_vectors()` - Search variables by keyword
|
|
84
|
+
* `parent_census_vectors()` - Navigate variable hierarchies upward
|
|
85
|
+
* `child_census_vectors()` - Navigate variable hierarchies downward
|
|
86
|
+
* `find_census_vectors()` - Enhanced variable search with fuzzy matching
|
|
87
|
+
|
|
88
|
+
### Geographic Capabilities
|
|
89
|
+
* GeoPandas integration for spatial analysis
|
|
90
|
+
* Multiple resolution options (simplified/high)
|
|
91
|
+
* Seamless geometry + data integration
|
|
92
|
+
|
|
93
|
+
### Reliability & Performance
|
|
94
|
+
* Production-grade error handling with helpful messages
|
|
95
|
+
* Automatic retry logic with exponential backoff
|
|
96
|
+
* Connection pooling for improved performance
|
|
97
|
+
* Rate limiting to respect API constraints
|
|
98
|
+
* Comprehensive caching system
|
|
99
|
+
|
|
100
|
+
## Installation
|
|
101
|
+
|
|
102
|
+
**Note**: pycancensus is not yet published on PyPI. Install directly from GitHub:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Install latest version from GitHub
|
|
106
|
+
pip install git+https://github.com/dshkol/pycancensus.git
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Or for development:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
git clone https://github.com/dshkol/pycancensus.git
|
|
113
|
+
cd pycancensus
|
|
114
|
+
pip install -e .[dev]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Coming soon**: Publication to PyPI for `pip install pycancensus`
|
|
118
|
+
|
|
119
|
+
## API Key
|
|
120
|
+
|
|
121
|
+
**pycancensus** requires a valid CensusMapper API key to use. You can obtain a free API key by [signing up](https://censusmapper.ca/users/sign_up) for a CensusMapper account.
|
|
122
|
+
|
|
123
|
+
Set your API key as an environment variable:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
export CANCENSUS_API_KEY="your_api_key_here"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Or set it programmatically:
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
import pycancensus as pc
|
|
133
|
+
pc.set_api_key("your_api_key_here")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Quick Start
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
import pycancensus as pc
|
|
140
|
+
|
|
141
|
+
# Set your API key
|
|
142
|
+
pc.set_api_key("your_api_key_here")
|
|
143
|
+
|
|
144
|
+
# List available datasets
|
|
145
|
+
datasets = pc.list_census_datasets()
|
|
146
|
+
|
|
147
|
+
# Discover variables with new hierarchy functions
|
|
148
|
+
vectors = pc.list_census_vectors("CA21")
|
|
149
|
+
income_vars = pc.search_census_vectors("income", "CA21")
|
|
150
|
+
related_vars = pc.child_census_vectors("v_CA21_1", dataset="CA21")
|
|
151
|
+
|
|
152
|
+
# Get census data
|
|
153
|
+
data = pc.get_census(
|
|
154
|
+
dataset="CA21",
|
|
155
|
+
regions={"CMA": "35535"}, # Toronto CMA
|
|
156
|
+
vectors=["v_CA21_1", "v_CA21_2", "v_CA21_3"], # Population by gender
|
|
157
|
+
level="CSD"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Get census data with geography for mapping
|
|
161
|
+
geo_data = pc.get_census(
|
|
162
|
+
dataset="CA21",
|
|
163
|
+
regions={"PR": "35"}, # Ontario
|
|
164
|
+
vectors=["v_CA21_1"], # Total population
|
|
165
|
+
level="CSD",
|
|
166
|
+
geo_format="geopandas" # Returns GeoDataFrame
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# Advanced: Compare multiple Census years
|
|
170
|
+
data_2021 = pc.get_census("CA21", {"CSD": "5915022"}, ["v_CA21_1"], "CSD")
|
|
171
|
+
data_2016 = pc.get_census("CA16", {"CSD": "5915022"}, ["v_CA16_401"], "CSD")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Variable Discovery Examples
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
# Search for housing-related variables
|
|
178
|
+
housing = pc.search_census_vectors("dwelling", "CA21")
|
|
179
|
+
|
|
180
|
+
# Navigate variable hierarchies
|
|
181
|
+
population_base = "v_CA21_1"
|
|
182
|
+
breakdowns = pc.child_census_vectors(population_base, dataset="CA21")
|
|
183
|
+
parent_categories = pc.parent_census_vectors(population_base, dataset="CA21")
|
|
184
|
+
|
|
185
|
+
# Enhanced search with fuzzy matching
|
|
186
|
+
income_vectors = pc.find_census_vectors("CA21", "median household income")
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Error Handling & Resilience
|
|
190
|
+
|
|
191
|
+
pycancensus includes production-grade error handling:
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
from pycancensus.resilience import CensusAPIError, RateLimitError
|
|
195
|
+
|
|
196
|
+
try:
|
|
197
|
+
data = pc.get_census("CA21", {"PR": "35"}, ["v_CA21_1"], "PR")
|
|
198
|
+
except RateLimitError as e:
|
|
199
|
+
print(f"Rate limited: {e}")
|
|
200
|
+
print(f"Retry after: {e.retry_after} seconds")
|
|
201
|
+
except CensusAPIError as e:
|
|
202
|
+
print(f"API error: {e}")
|
|
203
|
+
print(f"Suggestion: {e.suggestion}")
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Testing & Verification
|
|
207
|
+
|
|
208
|
+
pycancensus includes comprehensive testing to ensure reliability and R equivalence:
|
|
209
|
+
|
|
210
|
+
### Cross-Validation with R cancensus
|
|
211
|
+
- **4/4 tests passing** with full data equivalence
|
|
212
|
+
- Identical results for vector listing, data retrieval, and multi-region queries
|
|
213
|
+
- Automated testing against R cancensus library
|
|
214
|
+
|
|
215
|
+
### Integration Testing
|
|
216
|
+
- **6 real-world scenarios** covering typical data analysis workflows
|
|
217
|
+
- Provincial population analysis, demographic breakdowns, income analysis
|
|
218
|
+
- Vector hierarchy navigation, time series comparisons, geographic analysis
|
|
219
|
+
- Performance benchmarking with large datasets
|
|
220
|
+
|
|
221
|
+
### Robustness Testing
|
|
222
|
+
- Error handling with invalid regions/vectors
|
|
223
|
+
- Large dataset performance testing
|
|
224
|
+
- API resilience and retry logic validation
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Run the test suite
|
|
228
|
+
python -m pytest tests/ -v
|
|
229
|
+
|
|
230
|
+
# Run cross-validation against R
|
|
231
|
+
python tests/cross_validation/test_r_equivalence.py
|
|
232
|
+
|
|
233
|
+
# Run integration scenarios
|
|
234
|
+
python tests/integration/test_comprehensive_scenarios.py
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
See [`tests/cross_validation/results/`](tests/cross_validation/results/) for detailed test results and validation reports.
|
|
238
|
+
|
|
239
|
+
## Contributing
|
|
240
|
+
|
|
241
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on:
|
|
242
|
+
- Development setup
|
|
243
|
+
- Running tests
|
|
244
|
+
- Code style (Black, flake8)
|
|
245
|
+
- Submitting pull requests
|
|
246
|
+
- Reporting issues
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
251
|
+
|
|
252
|
+
## Related Packages
|
|
253
|
+
|
|
254
|
+
This package is inspired by and based on the R [cancensus](https://github.com/mountainMath/cancensus) package.
|
|
255
|
+
|
|
256
|
+
## Statistics Canada Attribution
|
|
257
|
+
|
|
258
|
+
Subject to the Statistics Canada Open Data License Agreement, licensed products using Statistics Canada data should employ the following acknowledgement of source:
|
|
259
|
+
|
|
260
|
+
**Acknowledgment of Source**
|
|
261
|
+
|
|
262
|
+
(a) You shall include and maintain the following notice on all licensed rights of the Information:
|
|
263
|
+
|
|
264
|
+
- Source: Statistics Canada, name of product, reference date. Reproduced and distributed on an "as is" basis with the permission of Statistics Canada.
|
|
265
|
+
|
|
266
|
+
(b) Where any Information is contained within a Value-added Product, you shall include on such Value-added Product the following notice:
|
|
267
|
+
|
|
268
|
+
- Adapted from Statistics Canada, name of product, reference date. This does not constitute an endorsement by Statistics Canada of this product.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# pycancensus
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://pycancensus.readthedocs.io/en/latest/?badge=latest)
|
|
6
|
+
[](tests/)
|
|
7
|
+
[](tests/cross_validation/)
|
|
8
|
+
|
|
9
|
+
Access, retrieve, and work with Canadian Census data and geography.
|
|
10
|
+
|
|
11
|
+
**pycancensus** is a Python package that provides integrated, convenient, and uniform access to Canadian Census data and geography retrieved using the CensusMapper API. This package produces analysis-ready tidy DataFrames and spatial data in multiple formats, with full equivalence to the R cancensus library.
|
|
12
|
+
|
|
13
|
+
## Recent Updates
|
|
14
|
+
|
|
15
|
+
- **Full R Library Equivalence**: Verified 100% data compatibility with R cancensus
|
|
16
|
+
- **Enhanced API Reliability**: Production-grade error handling and retry logic
|
|
17
|
+
- **Vector Hierarchy Functions**: Navigate census variable relationships like R
|
|
18
|
+
- **Improved Data Quality**: Fixed column naming and data processing issues
|
|
19
|
+
- **Comprehensive Testing**: 450+ integration tests covering real-world scenarios
|
|
20
|
+
- **National-Level Support**: Added level='C' for Canada-wide baseline comparisons
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
### Data Access
|
|
25
|
+
* Download Census data and geography in analysis-ready format
|
|
26
|
+
* Support for multiple Census years: 2021, 2016, 2011, 2006, 2001, 1996
|
|
27
|
+
* All Census geographic levels: PR, CMA, CD, CSD, CT, DA, EA, DB
|
|
28
|
+
* Taxfiler data at Census Tract level (2000-2018)
|
|
29
|
+
|
|
30
|
+
### Variable Discovery
|
|
31
|
+
* `list_census_vectors()` - Browse all available variables
|
|
32
|
+
* `search_census_vectors()` - Search variables by keyword
|
|
33
|
+
* `parent_census_vectors()` - Navigate variable hierarchies upward
|
|
34
|
+
* `child_census_vectors()` - Navigate variable hierarchies downward
|
|
35
|
+
* `find_census_vectors()` - Enhanced variable search with fuzzy matching
|
|
36
|
+
|
|
37
|
+
### Geographic Capabilities
|
|
38
|
+
* GeoPandas integration for spatial analysis
|
|
39
|
+
* Multiple resolution options (simplified/high)
|
|
40
|
+
* Seamless geometry + data integration
|
|
41
|
+
|
|
42
|
+
### Reliability & Performance
|
|
43
|
+
* Production-grade error handling with helpful messages
|
|
44
|
+
* Automatic retry logic with exponential backoff
|
|
45
|
+
* Connection pooling for improved performance
|
|
46
|
+
* Rate limiting to respect API constraints
|
|
47
|
+
* Comprehensive caching system
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
**Note**: pycancensus is not yet published on PyPI. Install directly from GitHub:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Install latest version from GitHub
|
|
55
|
+
pip install git+https://github.com/dshkol/pycancensus.git
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or for development:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/dshkol/pycancensus.git
|
|
62
|
+
cd pycancensus
|
|
63
|
+
pip install -e .[dev]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Coming soon**: Publication to PyPI for `pip install pycancensus`
|
|
67
|
+
|
|
68
|
+
## API Key
|
|
69
|
+
|
|
70
|
+
**pycancensus** requires a valid CensusMapper API key to use. You can obtain a free API key by [signing up](https://censusmapper.ca/users/sign_up) for a CensusMapper account.
|
|
71
|
+
|
|
72
|
+
Set your API key as an environment variable:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
export CANCENSUS_API_KEY="your_api_key_here"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Or set it programmatically:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import pycancensus as pc
|
|
82
|
+
pc.set_api_key("your_api_key_here")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Quick Start
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import pycancensus as pc
|
|
89
|
+
|
|
90
|
+
# Set your API key
|
|
91
|
+
pc.set_api_key("your_api_key_here")
|
|
92
|
+
|
|
93
|
+
# List available datasets
|
|
94
|
+
datasets = pc.list_census_datasets()
|
|
95
|
+
|
|
96
|
+
# Discover variables with new hierarchy functions
|
|
97
|
+
vectors = pc.list_census_vectors("CA21")
|
|
98
|
+
income_vars = pc.search_census_vectors("income", "CA21")
|
|
99
|
+
related_vars = pc.child_census_vectors("v_CA21_1", dataset="CA21")
|
|
100
|
+
|
|
101
|
+
# Get census data
|
|
102
|
+
data = pc.get_census(
|
|
103
|
+
dataset="CA21",
|
|
104
|
+
regions={"CMA": "35535"}, # Toronto CMA
|
|
105
|
+
vectors=["v_CA21_1", "v_CA21_2", "v_CA21_3"], # Population by gender
|
|
106
|
+
level="CSD"
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# Get census data with geography for mapping
|
|
110
|
+
geo_data = pc.get_census(
|
|
111
|
+
dataset="CA21",
|
|
112
|
+
regions={"PR": "35"}, # Ontario
|
|
113
|
+
vectors=["v_CA21_1"], # Total population
|
|
114
|
+
level="CSD",
|
|
115
|
+
geo_format="geopandas" # Returns GeoDataFrame
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Advanced: Compare multiple Census years
|
|
119
|
+
data_2021 = pc.get_census("CA21", {"CSD": "5915022"}, ["v_CA21_1"], "CSD")
|
|
120
|
+
data_2016 = pc.get_census("CA16", {"CSD": "5915022"}, ["v_CA16_401"], "CSD")
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Variable Discovery Examples
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
# Search for housing-related variables
|
|
127
|
+
housing = pc.search_census_vectors("dwelling", "CA21")
|
|
128
|
+
|
|
129
|
+
# Navigate variable hierarchies
|
|
130
|
+
population_base = "v_CA21_1"
|
|
131
|
+
breakdowns = pc.child_census_vectors(population_base, dataset="CA21")
|
|
132
|
+
parent_categories = pc.parent_census_vectors(population_base, dataset="CA21")
|
|
133
|
+
|
|
134
|
+
# Enhanced search with fuzzy matching
|
|
135
|
+
income_vectors = pc.find_census_vectors("CA21", "median household income")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Error Handling & Resilience
|
|
139
|
+
|
|
140
|
+
pycancensus includes production-grade error handling:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from pycancensus.resilience import CensusAPIError, RateLimitError
|
|
144
|
+
|
|
145
|
+
try:
|
|
146
|
+
data = pc.get_census("CA21", {"PR": "35"}, ["v_CA21_1"], "PR")
|
|
147
|
+
except RateLimitError as e:
|
|
148
|
+
print(f"Rate limited: {e}")
|
|
149
|
+
print(f"Retry after: {e.retry_after} seconds")
|
|
150
|
+
except CensusAPIError as e:
|
|
151
|
+
print(f"API error: {e}")
|
|
152
|
+
print(f"Suggestion: {e.suggestion}")
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Testing & Verification
|
|
156
|
+
|
|
157
|
+
pycancensus includes comprehensive testing to ensure reliability and R equivalence:
|
|
158
|
+
|
|
159
|
+
### Cross-Validation with R cancensus
|
|
160
|
+
- **4/4 tests passing** with full data equivalence
|
|
161
|
+
- Identical results for vector listing, data retrieval, and multi-region queries
|
|
162
|
+
- Automated testing against R cancensus library
|
|
163
|
+
|
|
164
|
+
### Integration Testing
|
|
165
|
+
- **6 real-world scenarios** covering typical data analysis workflows
|
|
166
|
+
- Provincial population analysis, demographic breakdowns, income analysis
|
|
167
|
+
- Vector hierarchy navigation, time series comparisons, geographic analysis
|
|
168
|
+
- Performance benchmarking with large datasets
|
|
169
|
+
|
|
170
|
+
### Robustness Testing
|
|
171
|
+
- Error handling with invalid regions/vectors
|
|
172
|
+
- Large dataset performance testing
|
|
173
|
+
- API resilience and retry logic validation
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Run the test suite
|
|
177
|
+
python -m pytest tests/ -v
|
|
178
|
+
|
|
179
|
+
# Run cross-validation against R
|
|
180
|
+
python tests/cross_validation/test_r_equivalence.py
|
|
181
|
+
|
|
182
|
+
# Run integration scenarios
|
|
183
|
+
python tests/integration/test_comprehensive_scenarios.py
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
See [`tests/cross_validation/results/`](tests/cross_validation/results/) for detailed test results and validation reports.
|
|
187
|
+
|
|
188
|
+
## Contributing
|
|
189
|
+
|
|
190
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on:
|
|
191
|
+
- Development setup
|
|
192
|
+
- Running tests
|
|
193
|
+
- Code style (Black, flake8)
|
|
194
|
+
- Submitting pull requests
|
|
195
|
+
- Reporting issues
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
200
|
+
|
|
201
|
+
## Related Packages
|
|
202
|
+
|
|
203
|
+
This package is inspired by and based on the R [cancensus](https://github.com/mountainMath/cancensus) package.
|
|
204
|
+
|
|
205
|
+
## Statistics Canada Attribution
|
|
206
|
+
|
|
207
|
+
Subject to the Statistics Canada Open Data License Agreement, licensed products using Statistics Canada data should employ the following acknowledgement of source:
|
|
208
|
+
|
|
209
|
+
**Acknowledgment of Source**
|
|
210
|
+
|
|
211
|
+
(a) You shall include and maintain the following notice on all licensed rights of the Information:
|
|
212
|
+
|
|
213
|
+
- Source: Statistics Canada, name of product, reference date. Reproduced and distributed on an "as is" basis with the permission of Statistics Canada.
|
|
214
|
+
|
|
215
|
+
(b) Where any Information is contained within a Value-added Product, you shall include on such Value-added Product the following notice:
|
|
216
|
+
|
|
217
|
+
- Adapted from Statistics Canada, name of product, reference date. This does not constitute an endorsement by Statistics Canada of this product.
|