Official, versioned Python packages for offline access to Country State City data with type hints and lazy loading.
| Package | PyPI | Description |
|---|---|---|
| countrystatecity-countries | 250 countries, 5,308 states, and 171,938 cities | |
| countrystatecity-timezones | 432 IANA timezones and time conversion utilities | |
| countrystatecity-currencies | 249 country/currency associations | |
| countrystatecity-translations | 4,724 country-name translations in 19 languages | |
| countrystatecity-phonecodes | International phone/dialing codes for 250 countries | |
| countrystatecity-regions | Region and subregion associations for 250 countries | |
| countrystatecity-postal-codes | Postal/ZIP records for 125 countries |
Note: There is no bare
countrystatecitypackage on PyPI. Always install with the suffix (-countries,-timezones,-currencies,-translations,-phonecodes,-regions,-postal-codes).
These packages provide versioned snapshots for offline use, development, and repeatable builds. For production applications that need regularly updated data, server-side search and filtering, field-selected responses, or managed availability and support, use the Country State City API.
Get a free API key Β· Read the API docs Β· Compare plans Β· Migration guide
API keys must stay in server-side environment variables, never in browser code or source control.
Install only what you need:
pip install countrystatecity-countries
pip install countrystatecity-timezones
pip install countrystatecity-currencies
pip install countrystatecity-translations
pip install countrystatecity-phonecodes
pip install countrystatecity-regions
pip install countrystatecity-postal-codesfrom countrystatecity_countries import (
get_countries,
get_country_by_code,
get_states_of_country,
get_cities_of_state,
)
# All countries
countries = get_countries()
print(f"Total countries: {len(countries)}")
# Specific country
usa = get_country_by_code("US")
print(f"{usa.emoji} {usa.name} β {usa.capital}")
print(f"Currency: {usa.currency_symbol} {usa.currency_name}")
# States and cities (lazy loaded)
states = get_states_of_country("US")
cities = get_cities_of_state("US", "CA")from countrystatecity_timezones import (
get_all_timezones,
get_timezones_by_country,
get_timezone_by_zone_name,
get_timezones_by_offset,
convert_time,
)
# Timezones for a country
timezones = get_timezones_by_country("US")
# Lookup by zone name
tz = get_timezone_by_zone_name("America/New_York")
print(f"{tz.zone_name} β {tz.gmt_offset_name}")
# Convert time between zones
from datetime import datetime
dt = datetime(2024, 1, 1, 12, 0, 0)
converted = convert_time(dt, "America/New_York", "Asia/Kolkata")from countrystatecity_currencies import (
get_all_currencies,
get_currency_by_country,
get_countries_by_currency,
search_currencies,
)
# Currency for a country
currency = get_currency_by_country("US")
print(f"{currency.symbol} {currency.name} ({currency.code})")
# All countries using a currency
countries = get_countries_by_currency("EUR")
# Search
results = search_currencies("dollar")from countrystatecity_phonecodes import (
get_all_phonecodes,
get_phonecode_by_country,
get_countries_by_phonecode,
search_phonecodes,
)
# Phone code for a country
us = get_phonecode_by_country("US")
print(f"+{us.phoneCode} β {us.countryName}") # +1 β United States
# All countries sharing a dialing code
plus1 = get_countries_by_phonecode("1")
print(f"{len(plus1)} countries use +1")
# Works with or without + prefix
plus44 = get_countries_by_phonecode("+44")
# Search
results = search_phonecodes("united")from countrystatecity_translations import (
get_all_translations,
get_translations_by_country,
get_translations_by_language,
get_translation,
search_translations,
)
# Country name in a specific language
translation = get_translation("US", "fr")
print(translation.name) # Γtats-Unis
# All translations for a country
translations = get_translations_by_country("IN")
# All countries translated in Japanese
japanese = get_translations_by_language("ja")from countrystatecity_regions import (
get_region_by_country,
get_countries_by_region,
get_countries_by_subregion,
get_all_region_names,
search_regions,
)
# Region/subregion for a country
region = get_region_by_country("US")
print(f"{region.region} β {region.subregion}") # Americas β Northern America
# All countries in a region
asian_countries = get_countries_by_region("Asia")
# All countries in a subregion
south_asia = get_countries_by_subregion("Southern Asia")
# List distinct regions
print(get_all_region_names()) # ['Africa', 'Americas', 'Asia', 'Europe', 'Oceania', 'Polar']
# Search
results = search_regions("southern asia")from countrystatecity_postal_codes import (
get_postal_info_by_country,
get_postcodes_of_country,
validate_postcode,
)
# Postal code format/regex for a country
us_info = get_postal_info_by_country("US")
print(us_info.postalCodeFormat) # #####-####
# Validate a postcode against the country's known format
validate_postcode("US", "10001") # True
# All postcodes for a country (lazy loaded)
postcodes = get_postcodes_of_country("AD")- β Type-safe with Pydantic models and mypy strict mode
- β Lazy loading for minimal memory footprint
- β 250 countries with metadata
- β 5,308 states/provinces
- β 171,938 cities
- β 432 timezones with GMT offsets and time conversion
- β 249 country/currency associations
- β 4,724 translations in 19 languages
- β Phone/dialing codes for 250 countries
- β Regions and subregions for 250 countries
- β 844,248 postal/ZIP-code records across 125 countries, with validation regexes for 189
- β Zero external dependencies (except Pydantic)
- β Python 3.8β3.12 support
- β Full test coverage with pytest
countrystatecity-pypi/
βββ python/
β βββ packages/
β βββ countries/ # countrystatecity-countries
β βββ timezones/ # countrystatecity-timezones
β βββ currencies/ # countrystatecity-currencies
β βββ translations/ # countrystatecity-translations
β βββ phonecodes/ # countrystatecity-phonecodes
β βββ regions/ # countrystatecity-regions
β βββ postal_codes/ # countrystatecity-postal-codes
β
βββ .github/
βββ workflows/
βββ python-ci.yml # CI β tests, type check, lint
βββ publish.yml # Publish to PyPI
βββ release.yml # Version bump + changelog
βββ update-data.yml # Weekly data sync
git clone https://github.com/dr5hn/countrystatecity-pypi.git
# Install a package in dev mode (replace 'countries' with any package)
cd python/packages/countries
pip install -e ".[dev]"
# Run tests
pytest --cov=countrystatecity_countries --cov-report=html
# Type check
mypy countrystatecity_countries/ --strict
# Lint and format
ruff check countrystatecity_countries/ tests/
black countrystatecity_countries/ tests/
isort countrystatecity_countries/ tests/| Component | Technology |
|---|---|
| Type System | Pydantic |
| Testing | pytest |
| Type Checking | mypy (strict) |
| Formatting | black + isort |
| Linting | ruff |
| CI/CD | GitHub Actions |
All packages are licensed under the Open Database License (ODbL-1.0).
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run tests (
pytest) - Commit your changes (
git commit -m 'Add amazing feature') - Open a Pull Request
- Issues: GitHub Issues
- Website: countrystatecity.in
- Production API: Get a free API key
- Pricing: Compare API plans
- countries-states-cities-database β Source database
- countrystatecity NPM β JavaScript/TypeScript packages
Made with β€οΈ by dr5hn