zipfinder
Complete offline postal-code / geocode database for Python. Works 100 % offline no internet connection required.
Features
- 1.8 million records — 121 countries, worldwide postal-code dataset
- O(1) lookups — hash-indexed, constant time regardless of dataset size
- O(log N) prefix search — bisect-based, no full-table scans ever
- Spatial radius search — geo-grid index, O(C + K·log K)
- TB / ZB scale — optional SQLite mode for datasets that exceed RAM
- Zero dependencies — Python standard library only
- Fully embedded — all data ships inside the package
Installation
pip install zipfinder
Quick Start
from zip_finder import lookup_zip, lookup_all_zips, search_zip, find_nearby_zips
# Exact lookup O(1)
record = lookup_zip("94107", country="US")
print(record["city"]) # San Francisco
print(record["latitude"]) # 37.7647
# Lookup without country returns first match across all countries
record = lookup_zip("94107")
# All countries sharing the same code O(1)
all_matches = lookup_all_zips("94107")
for r in all_matches:
print(r["country_code"], r["city"])
# Prefix search by zip or city O(log N + K)
results = search_zip("Lon", country="GB", limit=5)
for r in results:
print(r["postal_code"], r["city"])
# Nearby zip codes by coordinates O(C + Klog K)
nearby = find_nearby_zips(37.7749, -122.4194, radius_km=10, limit=5)
for r in nearby:
print(r["city"], r["distance_km"], "km")
API Reference
| Function | Description | Time Complexity |
|---|---|---|
lookup_zip(code, country=None) |
Single zip lookup, returns one record or None |
O(1) |
lookup_all_zips(code, country=None) |
All records for a zip across countries | O(1) |
search_zip(query, country=None, limit=10) |
Prefix search by zip or city name | O(log N + K) |
find_nearby_zips(lat, lon, radius_km=10, limit=10) |
Radius search by coordinates | O(C + Klog K) |
get_db_stats() |
Total records and country count | O(1) |
list_countries() |
Sorted list of all ISO-3166 country codes | O(1) |
get_database(use_sqlite=False) |
Access the raw database singleton |
Record format
Every returned dict contains:
{
"postal_code": "94107",
"city": "San Francisco",
"state": "California",
"state_code": "CA",
"country_code": "US",
"latitude": 37.7647,
"longitude": -122.4194,
"accuracy": 4
}
Results from find_nearby_zips also include a "distance_km" field.
Advanced Usage
Database statistics
from zip_finder import get_db_stats, list_countries
stats = get_db_stats()
print(f"Records : {stats['total_records']:,}") # 1,826,607
print(f"Countries: {stats['countries']}") # 121
countries = list_countries()
print(countries[:5]) # ['AD', 'AE', 'AI', 'AL', 'AR']
TB / ZB scale SQLite mode
For datasets that exceed available RAM:
from zip_finder import get_database
db = get_database(use_sqlite=True)
record = db.lookup_zip("94107", country="US")
Function Name Reference
All function names and their descriptions:
| Function | Description | Time Complexity |
|---|---|---|
lookup_zip(code, country=None) |
Single zip lookup, returns one record or None |
O(1) |
lookup_all_zips(code, country=None) |
All records for a zip across countries | O(1) |
search_zip(query, country=None, limit=10) |
Prefix search by zip or city name | O(log N + K) |
find_nearby_zips(lat, lon, radius_km=10, limit=10) |
Radius search by coordinates | O(C + K\u00b7log K) |
get_db_stats() |
Total records and country count | O(1) |
list_countries() |
Sorted list of all ISO-3166 country codes | O(1) |
get_database(use_sqlite=False) |
Access the raw database singleton |
Contributing
- Fork https://github.com/karthikbd/zipfinder
- Create a branch:
git checkout -b feature/my-feature - Run tests:
python -m pytest tests/ -v - Push and open a Pull Request
License
Metadata
Release files for zipfinder 2.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zipfinder-2.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Release files / zipfinder-2.0.3-py3-none-any.whl
| Download URL | zipfinder-2.0.3-py3-none-any.whl |
|---|---|
| Size | 58.9 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c7c68e233409e9107a2966ab11069fdf061e2c1299840906351e166bb88255cb
|
|
BLAKE2b-256 checksum How to use checksums |
fb5c47e5f990f5896ceaf9d81807232f119619dbba45f1d0e68ff4dddbae365f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.5
|
Security for zipfinder 2.0.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.