Skip to content

Commit 0d0ef62

Browse files
authored
Merge pull request #15 from buckmaxwell/develop
4.0.0
2 parents b3f4181 + 250ce16 commit 0d0ef62

10 files changed

Lines changed: 245 additions & 42877 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ dist
22
build
33
*.pyc
44
*.egg-info
5+
venv
56
.DS_Store

Changelog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
Version 4.0.0 2018-09-21
2+
* support for using a non-sqlite database
3+
* hascity method now returns cities where the city OR a secondary city matches
4+
by default with an option to specify primary only
5+
* IMPORTATNT. for legal adherence, the zipcodes are no longer packaged with this package
6+
and must be downloaded from
7+
https://www.unitedstateszipcodes.org/zip-code-database/ via the readme.
8+
19

210
Version 3.0.0 2018-06-17
311
* upgraded database to use data from unitedstateszipcodes.org

MANIFEST.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
include README.md
2-
recursive-include zipcode *.db

README.md

Lines changed: 62 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,80 @@
11
# Zipcode
22
### A simple python package for dealing with zip codes
33

4+
**IMPORTANT.** This package relies on up-to-date data from
5+
unitedstateszipcodes.org. To ensure that this package works, please follow the
6+
installation instructions closely, making sure that you also follow any rules
7+
governing zipcode data distributed by unitedstateszipcodes.org as per their
8+
site. The data is free for non-commercial use, and affordable for commercial
9+
use, you must download it from them though as I am not allowed to distribute it.
410

5-
**IMPORTANT.** This package uses up-to-date data from unitedstateszipcodes.org.
6-
If you wish to use this package for non-commercial purposes, please do! If you
7-
are using this as part of a commercial purpose, that is fine too, but before you
8-
do, you must buy a license to use this data from unitedstateszipcodes.org,
9-
[here](https://www.unitedstateszipcodes.org/zip-code-database/) - the license
10-
will be 40-200 dollars depending on the size of your business.
11+
## Installation
1112

13+
1. go to https://www.unitedstateszipcodes.org/zip-code-database/
14+
2. download the CSV file, pick free or a commercial version if you need to use
15+
it commercially. If you need to buy the commercial one, do so, but download
16+
the free one as that is the one supported by this package.
17+
3. move the downloaded file to a good location and set appropriate environment
18+
variables.
19+
```bash
20+
mkdir -p /var/lib/zipcode
21+
mv ~/Downloads/zip_code_database.csv /var/lib/zipcode/zip_code_database.csv
22+
echo 'ZIPS_CSV=/var/lib/zipcode/zip_code_database.csv' >> ~/.bash_profile
23+
source ~/.bash_profile
24+
```
25+
4. set up the database.
26+
- for production applications a relational database like
27+
postgresql is recommended! sqlite is acceptable for lower use applications.
28+
- after you decide which database to use, *find your connection string*
29+
[here](http://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine).
30+
```bash
31+
# set connection string, we use sqlite as an example (but use postgres in production!)
32+
echo 'ZIPCODE_CONNECTION_STRING=sqlite:///zipcode.db' >> ~/.bash_profile
33+
source ~/.bash_profile
34+
```
35+
5. install zipcode
36+
```bash
37+
pip install zipcode
38+
```
39+
6. populate the database
40+
- this might take a while ~10min for postgres. be patient, it'll be fast once loaded
41+
```bash
42+
build_zipcode_database
43+
```
44+
Good to go. The next section shows you how to use the package.
1245

1346
## Getting started
1447

15-
Simple package for dealing with zip codes in python.
16-
Full documentation at https://pythonhosted.org/zipcode
48+
```py
49+
import zipcode
1750

18-
>>> import zipcode
19-
>>>
20-
>>> myzip = zipcode.isequal('44102')
21-
>>> myzip.state #=> 'OH'
22-
>>> myzip.city #=> 'Cleveland'
23-
>>>
24-
>>> dict(myzip) #=> {'zip_type': u'STANDARD', 'city': u'Cleveland', 'decommissioned': 0, 'zip': u'44102', 'state': u'OH', 'secondary_cities': [u''], 'location': 'Cleveland, OH', 'area_codes': [u'216'], 'lat': 41.48, 'timezone': u'America/New_York', 'lng': -81.74, 'population': 31930}
25-
>>>
26-
>>> #all keys in the dictionary can be fetched with dot notation.
27-
>>>
28-
>>> zipcode.islike('00') #=> list of Zip objects that begin with given prefix.
29-
>>>
30-
>>> cbus = (39.98, -82.98)
31-
>>> zipcode.isinradius(cbus, 20) #=> list of all zip code objects within 20 miles of 'cbus'
32-
>>>
33-
>>>
34-
>>> zipcode.hascity('Cleveland', 'OH') #=> list of zip codes in Cleveland, OH
35-
>>> zipcode.hascity('', 'OH') #=> list of zip codes in OH
36-
>>>
37-
>>>
38-
>>> zipcode.hasareacode(216) #=> list of zip codes associated with 216
39-
40-
## Keeping the database up-to-date
51+
myzip = zipcode.isequal('44102')
52+
myzip.state #=> 'OH'
53+
myzip.city #=> 'Cleveland'
54+
myzip.location #=> 'Cleveland, OH'
4155

42-
Zip codes don't change very often, but the borders do change, and new zip codes
43-
are added, and others are removed. To keep your zipcode package ever up-to-date
44-
we suggest that you set up a job to keep the sqlite3 database current.
56+
# all keys in the dictionary can also be fetched with dot notation.
57+
dict(myzip) #=> {'zipcode': '44102', 'zipcode_type': 'STANDARD', 'city': 'Cleveland', 'state': 'OH', 'timezone': 'America/New_York', 'lat': 41.48, 'lng': -81.74, 'county': 'Cuyahoga County', 'location': 'Cleveland, OH', 'decommissioned': True, 'population': 31930, 'area_codes': ['216'], 'secondary_cities': []}
4558

46-
You'll pull the latest version of the database from our server once a month, and
47-
copy it to the install location of your current sqlite3 database.
4859

49-
```bash
50-
$ pip show zipcode
51-
Name: zipcode
52-
Version: 3.0.0
53-
Summary: A simple python package for dealing with zip codes in python.
54-
Home-page: https://github.com/buckmaxwell/zipcode
55-
Author: Max Buck
56-
Author-email: maxbuckdeveloper@gmail.com
57-
License: MIT
58-
Location: /<YOUR/<PATH>
59-
Requires: haversine
60-
```
60+
zipcode.islike('00') #=> list of Zip objects that begin with given prefix.
6161

62-
Note the location line. This is the top level of your version of the zipcode
63-
package. If the whole thing were set to a variable, the database would live at
64-
$LOCATION/zipcode.db - and look something like
65-
/<YOURPATH>/site-packages/zipcode/zipcode.db. For the next part imagine the
66-
whole path to the database is set to $DB_PATH.
62+
cbus = (39.98, -82.98)
63+
zipcode.isinradius(cbus, 20) #=> list of all zip code objects within 20 miles of 'cbus'
6764

68-
Now, take the following and modify the user agent to a value of your choice. The
69-
user agent must begin with robot. We ask that you limit your download requests
70-
to monthly - the database will not change more often than that. You can copy the
71-
script and put it in your crontab or a script that is run by your crontab.
65+
zipcode.hascity('Cleveland', 'OH') #=> list of zip codes in Cleveland, OH
66+
zipcode.hascity('', 'OH') #=> list of zip codes in state of OH
67+
zipcode.hascity('Flushing', 'NY', include_secondary=False) #=> don't include zips where flushing is a secondary city
7268

73-
```bash
74-
wget -d --header="User-Agent: robot/<SOME UNIQUE NAME>" https://maxwellbuck.com/downloads/zipcode.db.gz
75-
gunzip zipcode.db.gz
76-
cp zipcode.db $DB_PATH
69+
zipcode.hasareacode(216) #=> list of zip codes associated with 216
7770
```
7871

72+
## Keeping the database up-to-date
73+
74+
Zip codes don't change very often, but the borders do change, and new zip codes
75+
are added, and others are removed. To keep your zipcode package ever up-to-date
76+
we suggest that you set up a job to keep the database current, or simply drop
77+
the zipcodes table in your database and re-rerun steps 1-3 and 6 once every 3
78+
months or so.
79+
7980
You're all set. Get to it!

bin/build_zipcode_database

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
import csv
5+
import os
6+
from zipcode import Session, Zip, Base, engine
7+
print('dog')
8+
Base.metadata.create_all(engine)
9+
print('dog done!')
10+
11+
try:
12+
zips_csv = os.environ['ZIPS_CSV']
13+
except KeyError:
14+
raise Exception('ZIPS_CSV must be set to the full path of the csv'
15+
'downloaded from https://www.unitedstateszipcodes.org/zip-code-database/')
16+
17+
if __name__ == '__main__':
18+
with open(zips_csv) as f:
19+
session = Session()
20+
reader = csv.reader(f)
21+
"""zip,type,decommissioned,primary_city,acceptable_cities,
22+
unacceptable_cities,state,county,timezone,area_codes,
23+
world_region,country,latitude,longitude,
24+
irs_estimated_population_2015"""
25+
for i,row in enumerate(reader):
26+
if row[0] == 'zip':
27+
continue # header row
28+
print(row)
29+
zc = Zip(
30+
zipcode=row[0],
31+
zipcode_type=row[1],
32+
city=row[3],
33+
state=row[6],
34+
timezone=row[8],
35+
lat=float(row[12]),
36+
lng=float(row[13]),
37+
secondary_cities=row[4],
38+
county=row[7],
39+
decommissioned=bool(int(row[2])),
40+
estimated_population=int(row[14]),
41+
area_codes=row[9]
42+
)
43+
session.add(zc)
44+
try:
45+
session.commit()
46+
except Exception as e:
47+
session.rollback()
48+
print('error. session was rolled back')
49+
raise e
50+
session.close()

setup.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# Versions should comply with PEP440. For a discussion on single-sourcing
99
# the version across setup.py and the project code, see
1010
# https://packaging.python.org/en/latest/single_source_version.html
11-
version='3.0.1',
11+
version='4.0.0',
1212

1313
description='A simple python package for dealing with zip codes in python. Free for non commerial use, for commercial use, you need a license. Check out the README on GitHub for details.',
1414

@@ -54,19 +54,13 @@
5454
# You can just specify the packages manually here if your project is
5555
# simple. Or you can use find_packages().
5656
packages=find_packages(exclude=['contrib', 'docs', 'tests*']),
57+
scripts=['bin/build_zipcode_database',
58+
],
5759

5860
# List run-time dependencies here. These will be installed by pip when
5961
# your project is installed. For an analysis of "install_requires" vs pip's
6062
# requirements files see:
6163
# https://packaging.python.org/en/latest/requirements.html
62-
install_requires=['haversine'],
63-
64-
# If there are data files included in your packages that need to be
65-
# installed, specify them here. If using Python 2.6 or less, then these
66-
# have to be included in MANIFEST.in as well.
67-
#package_data={
68-
# 'zipcode': ['zipcode.db'],
69-
#},
70-
include_package_data=True
64+
install_requires=['haversine', 'SQLAlchemy'],
7165

7266
)

0 commit comments

Comments
 (0)