Part 4. Python Package Development
Overview
You’ve built powerful analyses throughout this course—pedestrian flow dashboards, network accessibility tools, and spatial data pipelines. But what happens when you want to reuse these tools in future projects? When you want to share them with colleagues? When you want to build upon your own work months later?
The answer is Python packaging—transforming your analysis scripts into reusable, installable, shareable software. This final chapter teaches you to create professional Python packages that you and others can install with a simple pip install your-package.
From Scripts to Packages
The Problem: Copy-Paste Hell
Consider this scenario:
# project1/analysis.py
def calculate_walkability(streets_gdf, amenities_gdf, buffer_m=800):
"""Calculate walkability scores..."""
# 50 lines of well-crafted code
# Months later in project2/analysis.py
def calculate_walkability(streets_gdf, amenities_gdf, buffer_m=800):
"""Calculate walkability scores..."""
# Same 50 lines, copied and pasted
# But you fixed a bug in project1 and forgot to update project2...The Solution: Packaged Code
# Once, in your package
pip install my-urban-toolkit
# Forever, in any project
from my_urban_toolkit import calculate_walkability
walkability = calculate_walkability(streets, amenities)What You Will Learn
This chapter covers the complete package development lifecycle:
Week 9: Structure and Building (?sec-package-fundamentals)
- Why packaging matters for urban analytics
- Package architecture: the
src/layout - Understanding
pyproject.toml - Building distributions with
uv - Testing packages locally
Week 10: Testing and Publishing (?sec-testing-quality)
- Writing tests with pytest
- Testing geospatial operations
- Documentation strategies
- Publishing to TestPyPI
- Troubleshooting publication issues
Week 11: Production Quality (?sec-geospatial-package-example)
- Real-world package examples
- CI/CD with GitHub Actions
- Publishing to PyPI
- Creating professional documentation
Week 12: Publishing to PyPI (?sec-publish-pypi)
- Production PyPI publication
- Version management
- Package maintenance
- Community engagement
Story Problem: The Auckland GIS Toolkit
Throughout this chapter, we’ll develop auckland-gis—a package that:
Provides reusable functions you’ve built across assignments: - Loading and validating Auckland SA2 boundaries - Calculating accessibility metrics - Processing pedestrian count data - Generating standard choropleth maps - Computing urban form indicators
Solves common problems: - Students stop copying code between projects - CRS validation becomes standardized - Analysis becomes easier to teach and review - Results are reproducible
Enables future work: - Import in Jupyter notebooks: from auckland_gis import load_sa2 - Use in dashboards: from auckland_gis.viz import create_choropleth - Share with colleagues: pip install auckland-gis
The Journey: Scripts → Package → Publication
Phase 1: From Notebook to Module (Week 9)
Starting point: Scattered code across notebooks and scripts
my_analysis/
├── load_data.py
├── process_pedestrians.py
├── calculate_metrics.py
└── make_maps.py
Week 9 deliverable: Organized package structure
auckland-gis/
├── src/
│ └── auckland_gis/
│ ├── __init__.py
│ ├── data.py
│ ├── metrics.py
│ └── viz.py
├── tests/
│ └── test_data.py
├── pyproject.toml
└── README.md
Phase 2: Add Quality Assurance (Week 10)
Tests ensure correctness:
def test_load_sa2():
"""Test SA2 loading validates CRS"""
gdf = load_sa2('data/auckland_sa2.gpkg')
assert gdf.crs == 'EPSG:2193'
assert len(gdf) > 0Documentation aids users:
def calculate_density(gdf, pop_column='population'):
"""
Calculate population density per km².
Parameters
----------
gdf : GeoDataFrame
Must contain geometry and population data
pop_column : str, default 'population'
Name of population column
Returns
-------
GeoDataFrame
Input GDF with added 'density' column
"""Learning Objectives
By the end of this chapter, you will be able to:
Technical Skills: - Structure Python packages using best practices - Write pyproject.toml configuration - Build wheel and source distributions - Write comprehensive tests with pytest - Generate documentation with docstrings - Publish packages to PyPI - Set up CI/CD pipelines - Version packages semantically
Geospatial Skills: - Test spatial operations correctly - Handle CRS validation in packages - Package spatial data appropriately - Manage geospatial dependencies - Create reusable GIS workflows
Professional Skills: - Write code others can understand and use - Document for diverse audiences - Troubleshoot publication issues - Maintain open source projects - Communicate technical work effectively
Why This Matters for Urban Analytics
1. Reproducibility
Published packages ensure analyses can be reproduced:
# Requirements file for research paper
auckland-gis==1.2.0 # Exact version locks analysis
geopandas==0.14.0Anyone can recreate your analysis with the same tools.
2. Collaboration
Teams work more efficiently with shared tools:
# Everyone uses the same validated functions
from auckland_gis import load_sa2, validate_join
sa2 = load_sa2('data/boundaries.gpkg')
data = validate_join(sa2, census_df, key='SA2_code')No more “it works on my machine” problems.
3. Teaching
Packages make teaching cleaner:
# In your course materials
pip install auckland-gis
# Students focus on analysis, not data wrangling
from auckland_gis import load_pedestrian_counts
data = load_pedestrian_counts('2023-03')4. Career Development
Employability: Employers value developers who can create reusable tools
Portfolio: Published packages demonstrate your skills publicly
Community: Contributing to open source builds professional networks
Impact: Your tools can influence research and practice beyond your direct work
Urban Analytics Package Ecosystem
You’ll join a rich ecosystem of geospatial packages:
Foundation Libraries (what you’ll depend on): - geopandas: Spatial DataFrames - shapely: Geometric operations - osmnx: Street networks - r5py: Routing and accessibility - folium: Interactive maps
Your Package (what you’ll create): - auckland-gis: Auckland-specific utilities - Or: urban-walkability: Walkability assessment tools - Or: escooter-analytics: Micromobility analysis - Or: accessibility-metrics: Transport accessibility
Impact: Your package could become someone else’s foundation library!
Assessment Overview
Package development spans the final four weeks:
| Week | Activity | Weight |
|---|---|---|
| 9 | Build first package locally | Completion credit |
| 10 | Publish to TestPyPI | 5% |
| 11 | Refinement and CI/CD | Part of Assignment 3 |
| 12 | Assignment 3: PyPI publication | 30% |
| 12 | Poster showcase | 10% |
Total: 45% of final grade
Chapter Structure
?sec-package-fundamentals: Package Structure and Building
Learn the fundamentals: - Why packaging matters for GIS workflows - Package architecture (src/ layout best practices) - Understanding pyproject.toml configuration - Building distributions with uv - Local testing before publication
Week 9 focus: Get everyone building packages successfully
?sec-testing-quality: Testing and Quality Assurance
Add robustness: - Writing tests with pytest - Testing geospatial operations - Handling edge cases (empty geometries, CRS issues) - Documentation strategies - TestPyPI publication
Week 10 focus: Practice publication in safe environment
?sec-geospatial-package-example: Real-World Package Examples
See it in action: - Complete package walkthroughs - Auckland utilities toolkit - Micromobility analysis example - CI/CD setup with GitHub Actions - Advanced packaging patterns
Week 11 focus: Polish for production release
?sec-publish-pypi: Publishing to Production PyPI
Final release: - Real PyPI publication process - Semantic versioning strategies - Release notes and changelogs - Package maintenance - Community engagement
Week 12 focus: Complete Assignment 3 and showcase
Real-World Applications
Example 1: Research Lab Toolkit
# The problem: Lab members copy code between projects
# The solution:
pip install lab-spatial-toolkit
from lab_spatial_toolkit import (
load_study_area,
calculate_accessibility,
generate_report
)Example 2: Consulting Deliverable
# The problem: Clients need reproducible analysis
# The solution: Deliver code as a package
pip install auckland-transport-analysis==2.1.0
# Client can reproduce all report figures
from auckland_transport_analysis import generate_figures
figures = generate_figures('data/')Example 3: Course Infrastructure
# The problem: Students struggle with data loading
# The solution: Package handles complexity
pip install gisci343-toolkit
from gisci343_toolkit import load_assignment_data
pedestrians, boundaries, network = load_assignment_data(assignment=2)Getting Started
Before you begin:
Prerequisites: - Python 3.10 or later - uv installed: pip install uv - Git and GitHub account - TestPyPI account (create in Week 10) - PyPI account (create in Week 11)
Development Tools: - Code editor (VS Code, PyCharm, or similar) - Terminal/command line - Git for version control
Conceptual Knowledge: - Python modules and imports - Functions and classes - Command line basics - Git fundamentals
Mindset for Package Development
Think like a library author: - “Will this make sense to someone else?” - “What might go wrong with this input?” - “How do I explain this clearly?”
Embrace iteration: - Version 1.0 doesn’t need to be perfect - Release early, improve based on feedback - Documentation can always improve
Value reproducibility: - Pin dependencies - Test thoroughly - Document assumptions - Version thoughtfully
Looking Ahead: Assignment 3
Throughout these weeks, you’ll work toward Assignment 3: a complete, published Python package. Suggested scopes:
Urban Accessibility: - Isochrone calculation tools - 15-minute city assessment - Multi-modal accessibility metrics
Micromobility Analysis: - E-scooter trip analysis - Geofencing validation - OD flow calculations - Mode share analytics
Urban Form: - Street connectivity metrics - Building morphology analysis - Walkability scoring - Network resilience measures
Transport Analytics: - Travel time calculations - Route choice modeling - Congestion assessment - Public transport accessibility
Choose something that: 1. Solves a real problem (yours or others’) 2. Builds on your assignments (reuse working code) 3. Interests you (you’ll work on this for 3-4 weeks) 4. Has clear scope (achievable in time available)
Course Wrap-Up: Poster Showcase
The course culminates in a poster showcase where you’ll present your package:
Format: A1 poster (594mm × 841mm) Content: Package purpose, features, use cases, results Audience: Faculty, students, potential employers Opportunity: Network, get feedback, showcase skills
This is your chance to demonstrate everything you’ve learned: technical skills, analytical thinking, and professional communication.
Let’s Begin
Package development transforms you from a code user to a code creator. You’ll learn to build tools that last, share knowledge effectively, and contribute to the broader geospatial community.
Ready to publish your first package? Let’s start with the fundamentals in ?sec-package-fundamentals.
Resources
Essential Reading: - Python Packaging Guide: https://packaging.python.org/ - uv documentation: https://docs.astral.sh/uv/ - pytest documentation: https://docs.pytest.org/ - Real Python - Python Packages: https://realpython.com/python-modules-packages/
Example Packages to Study: - osmnx: https://github.com/gboeing/osmnx - geopandas: https://github.com/geopandas/geopandas - momepy: https://github.com/pysal/momepy - r5py: https://github.com/r5py/r5py
Community: - Python Packaging Discord: https://discord.gg/pypa - PyPI: https://pypi.org/ - TestPyPI: https://test.pypi.org/
What Success Looks Like
By Week 12, you’ll be able to say:
✅ “I am a published Python package author” ✅ “My code is tested and documented” ✅ “Anyone can install my package with pip” ✅ “I understand package architecture and best practices” ✅ “I can maintain and version my package” ✅ “I’ve contributed to the open source ecosystem”
Most importantly: You’ll have created something that outlasts the course—a tool that you and others can use for years to come.
Let’s build something great.