# Zipcodes
Zipcodes is a simple library for querying U.S. zipcodes.
The Python `sqlite3` module is not required in order to use this package.
```python
>>> import zipcodes
>>> assert zipcodes.is_real('77429')
>>> assert len(zipcodes.similar_to('7742')) != 0
>>> exact_zip = zipcodes.matching('77429')[0]
>>> filtered_zips = zipcodes.filter_by(city="Cypress", state="TX")
>>> assert exact_zip in filtered_zips
>>> pprint.pprint(exact_zip)
{'acceptable_cities': [],
'active': True,
'area_codes': ['281', '832'],
'city': 'Cypress',
'country': 'US',
'county': 'Harris County',
'lat': '29.9857',
'long': '-95.6548',
'state': 'TX',
'timezone': 'America/Chicago',
'unacceptable_cities': [],
'world_region': 'NA',
'zip_code': '77429',
'zip_code_type': 'STANDARD'}[
```
⚠️ The zipcode data was last updated on: **Feb. 16, 2025** ⚠️
[](https://pepy.tech/project/zipcodes/month)
[](https://pypi.org/project/zipcodes)
[](https://github.com/seanpianka/zipcodes/graphs/contributors)
## Installation
Zipcodes is available on PyPI:
```console
$ python -m pip install zipcodes
```
Zipcodes supports Python 2.6+ and Python 3.2+.
### Compiling with PyInstaller
Add a data file to your PyInstaller bundle with the [`--add-data`](https://pyinstaller.readthedocs.io/en/stable/spec-files.html#adding-data-files) flag.
#### Linux and MacOS
`--add-data "<path-to-package-install>/zipcodes/zips.json.bz2:zipcodes"`
#### Windows
`--add-data "<path-to-package-install>\zipcodes\zips.json.bz2;zipcodes"`
## Zipcode Data
The build script for the zipcode data outputs a JSON file containing all the zipcode data and zipped using bzip2. The data sources are stored under `build/app/data`.
Build the zipcode data for distribution:
```shell script
$ build/app/__init__.py # outputs `zipcodes/zips.json.bz2`
```
## Tests
The tests are defined in a declarative, table-based format that generates test
cases.
Run the tests directly:
```shell script
$ python tests/__init__.py
```
## Examples
```python
>>> from pprint import pprint
>>> import zipcodes
>>> # Simple zip-code matching.
>>> pprint(zipcodes.matching('77429'))
[{'acceptable_cities': [],
'active': True,
'area_codes': ['281', '832'],
'city': 'Cypress',
'country': 'US',
'county': 'Harris County',
'lat': '29.9857',
'long': '-95.6548',
'state': 'TX',
'timezone': 'America/Chicago',
'unacceptable_cities': [],
'world_region': 'NA',
'zip_code': '77429',
'zip_code_type': 'STANDARD'}]
>>> # Handles of Zip+4 zip-codes nicely. :)
>>> pprint(zipcodes.matching('77429-1145'))
[{'acceptable_cities': [],
'active': True,
'area_codes': ['281', '832'],
'city': 'Cypress',
'country': 'US',
'county': 'Harris County',
'lat': '29.9857',
'long': '-95.6548',
'state': 'TX',
'timezone': 'America/Chicago',
'unacceptable_cities': [],
'world_region': 'NA',
'zip_code': '77429',
'zip_code_type': 'STANDARD'}]
>>> # Will try to handle invalid zip-codes gracefully...
>>> print(zipcodes.matching('06463'))
[]
>>> # Until it cannot.
>>> zipcodes.matching('0646a')
Traceback (most recent call last):
...
ValueError: Invalid characters, zipcode may only contain digits and "-".
>>> zipcodes.matching('064690')
Traceback (most recent call last):
...
ValueError: Invalid format, zipcode must be of the format: "#####" or "#####-####"
>>> zipcodes.matching(None)
Traceback (most recent call last):
...
TypeError: Invalid type, zipcode must be a string.
>>> # Whether the zip-code exists within the database.
>>> print(zipcodes.is_real('06463'))
False
>>> # How handy!
>>> print(zipcodes.is_real('06469'))
True
>>> # Search for zipcodes that begin with a pattern.
>>> pprint(zipcodes.similar_to('1018'))
[{'acceptable_cities': [],
'active': False,
'area_codes': ['212'],
'city': 'New York',
'country': 'US',
'county': 'New York County',
'lat': '40.71',
'long': '-74',
'state': 'NY',
'timezone': 'America/New_York',
'unacceptable_cities': ['J C Penney'],
'world_region': 'NA',
'zip_code': '10184',
'zip_code_type': 'UNIQUE'},
{'acceptable_cities': [],
'active': True,
'area_codes': ['212'],
'city': 'New York',
'country': 'US',
'county': 'New York County',
'lat': '40.7143',
'long': '-74.0067',
'state': 'NY',
'timezone': 'America/New_York',
'unacceptable_cities': [],
'world_region': 'NA',
'zip_code': '10185',
'zip_code_type': 'PO BOX'}]
>>> # Use filter_by to filter a list of zip-codes by specific attribute->value pairs.
>>> pprint(zipcodes.filter_by(city="Old Saybrook"))
[{'acceptable_cities': [],
'active': True,
'area_codes': ['860'],
'city': 'Old Saybrook',
'country': 'US',
'county': 'Middlesex County',
'lat': '41.3015',
'long': '-72.3879',
'state': 'CT',
'timezone': 'America/New_York',
'unacceptable_cities': ['Fenwick'],
'world_region': 'NA',
'zip_code': '06475',
'zip_code_type': 'STANDARD'}]
>>> # Arbitrary nesting of similar_to and filter_by calls, allowing for great precision while filtering.
>>> pprint(zipcodes.similar_to('2', zips=zipcodes.filter_by(active=True, city='Windsor')))
[{'acceptable_cities': [],
'active': True,
'area_codes': ['757'],
'city': 'Windsor',
'country': 'US',
'county': 'Isle of Wight County',
'lat': '36.8628',
'long': '-76.7143',
'state': 'VA',
'timezone': 'America/New_York',
'unacceptable_cities': [],
'world_region': 'NA',
'zip_code': '23487',
'zip_code_type': 'STANDARD'},
{'acceptable_cities': ['Askewville'],
'active': True,
'area_codes': ['252'],
'city': 'Windsor',
'country': 'US',
'county': 'Bertie County',
'lat': '35.9942',
'long': '-76.9422',
'state': 'NC',
'timezone': 'America/New_York',
'unacceptable_cities': [],
'world_region': 'NA',
'zip_code': '27983',
'zip_code_type': 'STANDARD'},
{'acceptable_cities': [],
'active': True,
'area_codes': ['803'],
'city': 'Windsor',
'country': 'US',
'county': 'Aiken County',
'lat': '33.4730',
'long': '-81.5132',
'state': 'SC',
'timezone': 'America/New_York',
'unacceptable_cities': [],
'world_region': 'NA',
'zip_code': '29856',
'zip_code_type': 'STANDARD'}]
>>> # Have any other ideas? Make a pull request and start contributing today!
>>> # Made with love by Sean Pianka
```
Raw data
{
"_id": null,
"home_page": null,
"name": "zipcodes",
"maintainer": null,
"docs_url": null,
"requires_python": ">=2.6",
"maintainer_email": null,
"keywords": "zipcode, zip, code, us, state, query, filter, validate, sqlite",
"author": null,
"author_email": "Sean Pianka <pianka@eml.cc>",
"download_url": "https://files.pythonhosted.org/packages/d4/52/925e88bce7af455d2a444c5df379427f6f3e3979345dac89542e1cce283e/zipcodes-1.3.0.tar.gz",
"platform": null,
"description": "# Zipcodes\n\nZipcodes is a simple library for querying U.S. zipcodes.\n\nThe Python `sqlite3` module is not required in order to use this package.\n\n```python\n>>> import zipcodes\n>>> assert zipcodes.is_real('77429')\n>>> assert len(zipcodes.similar_to('7742')) != 0\n>>> exact_zip = zipcodes.matching('77429')[0]\n>>> filtered_zips = zipcodes.filter_by(city=\"Cypress\", state=\"TX\") \n>>> assert exact_zip in filtered_zips\n>>> pprint.pprint(exact_zip)\n{'acceptable_cities': [],\n 'active': True,\n 'area_codes': ['281', '832'],\n 'city': 'Cypress',\n 'country': 'US',\n 'county': 'Harris County',\n 'lat': '29.9857',\n 'long': '-95.6548',\n 'state': 'TX',\n 'timezone': 'America/Chicago',\n 'unacceptable_cities': [],\n 'world_region': 'NA',\n 'zip_code': '77429',\n 'zip_code_type': 'STANDARD'}[\n```\n\n\u26a0\ufe0f The zipcode data was last updated on: **Feb. 16, 2025** \u26a0\ufe0f\n\n[](https://pepy.tech/project/zipcodes/month)\n[](https://pypi.org/project/zipcodes)\n[](https://github.com/seanpianka/zipcodes/graphs/contributors)\n\n\n## Installation\n\nZipcodes is available on PyPI:\n\n```console\n$ python -m pip install zipcodes\n```\n\nZipcodes supports Python 2.6+ and Python 3.2+.\n\n### Compiling with PyInstaller\n\nAdd a data file to your PyInstaller bundle with the [`--add-data`](https://pyinstaller.readthedocs.io/en/stable/spec-files.html#adding-data-files) flag.\n\n\n#### Linux and MacOS\n`--add-data \"<path-to-package-install>/zipcodes/zips.json.bz2:zipcodes\"`\n\n#### Windows\n`--add-data \"<path-to-package-install>\\zipcodes\\zips.json.bz2;zipcodes\"`\n\n## Zipcode Data\n\nThe build script for the zipcode data outputs a JSON file containing all the zipcode data and zipped using bzip2. The data sources are stored under `build/app/data`. \n\nBuild the zipcode data for distribution: \n\n```shell script\n$ build/app/__init__.py # outputs `zipcodes/zips.json.bz2`\n```\n\n\n## Tests\n\nThe tests are defined in a declarative, table-based format that generates test\ncases. \n\nRun the tests directly:\n\n```shell script\n$ python tests/__init__.py \n```\n\n## Examples\n\n```python\n>>> from pprint import pprint\n>>> import zipcodes\n\n>>> # Simple zip-code matching.\n>>> pprint(zipcodes.matching('77429'))\n[{'acceptable_cities': [],\n 'active': True,\n 'area_codes': ['281', '832'],\n 'city': 'Cypress',\n 'country': 'US',\n 'county': 'Harris County',\n 'lat': '29.9857',\n 'long': '-95.6548',\n 'state': 'TX',\n 'timezone': 'America/Chicago',\n 'unacceptable_cities': [],\n 'world_region': 'NA',\n 'zip_code': '77429',\n 'zip_code_type': 'STANDARD'}]\n\n\n>>> # Handles of Zip+4 zip-codes nicely. :)\n>>> pprint(zipcodes.matching('77429-1145'))\n[{'acceptable_cities': [],\n 'active': True,\n 'area_codes': ['281', '832'],\n 'city': 'Cypress',\n 'country': 'US',\n 'county': 'Harris County',\n 'lat': '29.9857',\n 'long': '-95.6548',\n 'state': 'TX',\n 'timezone': 'America/Chicago',\n 'unacceptable_cities': [],\n 'world_region': 'NA',\n 'zip_code': '77429',\n 'zip_code_type': 'STANDARD'}]\n\n>>> # Will try to handle invalid zip-codes gracefully...\n>>> print(zipcodes.matching('06463'))\n[]\n\n>>> # Until it cannot.\n>>> zipcodes.matching('0646a')\nTraceback (most recent call last):\n ...\nValueError: Invalid characters, zipcode may only contain digits and \"-\".\n\n>>> zipcodes.matching('064690')\nTraceback (most recent call last):\n ...\nValueError: Invalid format, zipcode must be of the format: \"#####\" or \"#####-####\"\n\n>>> zipcodes.matching(None)\nTraceback (most recent call last):\n ...\nTypeError: Invalid type, zipcode must be a string.\n\n>>> # Whether the zip-code exists within the database.\n>>> print(zipcodes.is_real('06463'))\nFalse\n\n>>> # How handy!\n>>> print(zipcodes.is_real('06469'))\nTrue\n\n>>> # Search for zipcodes that begin with a pattern.\n>>> pprint(zipcodes.similar_to('1018'))\n[{'acceptable_cities': [],\n 'active': False,\n 'area_codes': ['212'],\n 'city': 'New York',\n 'country': 'US',\n 'county': 'New York County',\n 'lat': '40.71',\n 'long': '-74',\n 'state': 'NY',\n 'timezone': 'America/New_York',\n 'unacceptable_cities': ['J C Penney'],\n 'world_region': 'NA',\n 'zip_code': '10184',\n 'zip_code_type': 'UNIQUE'},\n {'acceptable_cities': [],\n 'active': True,\n 'area_codes': ['212'],\n 'city': 'New York',\n 'country': 'US',\n 'county': 'New York County',\n 'lat': '40.7143',\n 'long': '-74.0067',\n 'state': 'NY',\n 'timezone': 'America/New_York',\n 'unacceptable_cities': [],\n 'world_region': 'NA',\n 'zip_code': '10185',\n 'zip_code_type': 'PO BOX'}]\n\n>>> # Use filter_by to filter a list of zip-codes by specific attribute->value pairs.\n>>> pprint(zipcodes.filter_by(city=\"Old Saybrook\"))\n[{'acceptable_cities': [],\n 'active': True,\n 'area_codes': ['860'],\n 'city': 'Old Saybrook',\n 'country': 'US',\n 'county': 'Middlesex County',\n 'lat': '41.3015',\n 'long': '-72.3879',\n 'state': 'CT',\n 'timezone': 'America/New_York',\n 'unacceptable_cities': ['Fenwick'],\n 'world_region': 'NA',\n 'zip_code': '06475',\n 'zip_code_type': 'STANDARD'}]\n\n>>> # Arbitrary nesting of similar_to and filter_by calls, allowing for great precision while filtering.\n>>> pprint(zipcodes.similar_to('2', zips=zipcodes.filter_by(active=True, city='Windsor')))\n[{'acceptable_cities': [],\n 'active': True,\n 'area_codes': ['757'],\n 'city': 'Windsor',\n 'country': 'US',\n 'county': 'Isle of Wight County',\n 'lat': '36.8628',\n 'long': '-76.7143',\n 'state': 'VA',\n 'timezone': 'America/New_York',\n 'unacceptable_cities': [],\n 'world_region': 'NA',\n 'zip_code': '23487',\n 'zip_code_type': 'STANDARD'},\n {'acceptable_cities': ['Askewville'],\n 'active': True,\n 'area_codes': ['252'],\n 'city': 'Windsor',\n 'country': 'US',\n 'county': 'Bertie County',\n 'lat': '35.9942',\n 'long': '-76.9422',\n 'state': 'NC',\n 'timezone': 'America/New_York',\n 'unacceptable_cities': [],\n 'world_region': 'NA',\n 'zip_code': '27983',\n 'zip_code_type': 'STANDARD'},\n {'acceptable_cities': [],\n 'active': True,\n 'area_codes': ['803'],\n 'city': 'Windsor',\n 'country': 'US',\n 'county': 'Aiken County',\n 'lat': '33.4730',\n 'long': '-81.5132',\n 'state': 'SC',\n 'timezone': 'America/New_York',\n 'unacceptable_cities': [],\n 'world_region': 'NA',\n 'zip_code': '29856',\n 'zip_code_type': 'STANDARD'}]\n\n>>> # Have any other ideas? Make a pull request and start contributing today!\n>>> # Made with love by Sean Pianka\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "Query U.S. state zipcodes without SQLite.",
"version": "1.3.0",
"project_urls": {
"Homepage": "https://github.com/seanpianka/zipcodes",
"Issues": "https://github.com/seanpianka/zipcodes/issues"
},
"split_keywords": [
"zipcode",
" zip",
" code",
" us",
" state",
" query",
" filter",
" validate",
" sqlite"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e0f5c5cfbe4a833ad967c130a8946eb093ec2f163d41d0c90b5df99aa8f61748",
"md5": "aa01c78e5706773a8fa443731f5a3c1f",
"sha256": "0da407f1c7e7c0bb93fc91da00c4bb95dc88b545c2ff04febdff5168e9ab8b2f"
},
"downloads": -1,
"filename": "zipcodes-1.3.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "aa01c78e5706773a8fa443731f5a3c1f",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=2.6",
"size": 726729,
"upload_time": "2025-02-16T06:17:37",
"upload_time_iso_8601": "2025-02-16T06:17:37.984803Z",
"url": "https://files.pythonhosted.org/packages/e0/f5/c5cfbe4a833ad967c130a8946eb093ec2f163d41d0c90b5df99aa8f61748/zipcodes-1.3.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d452925e88bce7af455d2a444c5df379427f6f3e3979345dac89542e1cce283e",
"md5": "9cfe945ed45acf80e5962c0eeb1e963a",
"sha256": "6a8d663f8477b54806b0af01bd90bfa2ba88e8e79be824a44e37697c69d064ef"
},
"downloads": -1,
"filename": "zipcodes-1.3.0.tar.gz",
"has_sig": false,
"md5_digest": "9cfe945ed45acf80e5962c0eeb1e963a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.6",
"size": 729212,
"upload_time": "2025-02-16T06:17:40",
"upload_time_iso_8601": "2025-02-16T06:17:40.384246Z",
"url": "https://files.pythonhosted.org/packages/d4/52/925e88bce7af455d2a444c5df379427f6f3e3979345dac89542e1cce283e/zipcodes-1.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-16 06:17:40",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "seanpianka",
"github_project": "zipcodes",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "zipcodes"
}