Skip to content

Legacy API

The legacy API provides 100% backwards compatibility with the original uszipcode library. This ensures that existing code can migrate to ZipSearch without any modifications.

Overview

The SearchEngine class maintains the exact same interface as the original uszipcode.SearchEngine, but with dramatically improved performance through pre-built RAM indices.

Migration

Simply change your import statement:

1
2
3
4
5
6
7
8
9
# Before
from uszipcode import SearchEngine

# After  
from zipsearch import SearchEngine

# Everything else stays exactly the same
search = SearchEngine()
zipcode = search.by_zipcode("10001")

Query Method

The query method provides the most flexible search interface, supporting multiple search patterns and filters in a single call.

Backwards compatible query method for searching zipcode data.

This method provides compatibility with the original zipsearch API while leveraging the new fast search infrastructure. It supports multiple search patterns and filters to find zipcodes based on various criteria.

Args: zipcode (str, optional): Exact zipcode to lookup (e.g., "90210") prefix (str, optional): Zipcode prefix to search (e.g., "902" finds all 902xx codes) pattern (str, optional): Pattern to search within zipcode strings city (str, optional): City name to search for state (str, optional): State abbreviation (e.g., "CA", "NY") lat (float, optional): Latitude for coordinate-based search lng (float, optional): Longitude for coordinate-based search radius (float, optional): Search radius in miles (requires lat/lng) zipcode_type (ZipcodeTypeEnum, optional): Filter by zipcode type (STANDARD, PO_BOX, etc.) sort_by (str, optional): Sort criteria (e.g., SORT_BY_DIST for distance) ascending (bool, optional): Sort order direction. Defaults to True. returns (int, optional): Maximum number of results to return **kwargs: Additional demographic filters including: - population_lower (int): Minimum population threshold - population_upper (int): Maximum population threshold - median_household_income_lower (int): Minimum income threshold - median_household_income_upper (int): Maximum income threshold - median_home_value_lower (int): Minimum home value threshold - median_home_value_upper (int): Maximum home value threshold

Returns: list[FastZipcode]: List of matching zipcode objects. Returns empty list if no matches.

Examples: >>> engine = SearchEngine() >>> # Single zipcode lookup >>> results = engine.query(zipcode="90210") >>> >>> # Find all zipcodes starting with 902 >>> results = engine.query(prefix="902") >>> >>> # Search by city and state >>> results = engine.query(city="Beverly Hills", state="CA") >>> >>> # Coordinate search within 10 miles >>> results = engine.query(lat=34.0901, lng=-118.4065, radius=10) >>> >>> # Demographic filtering >>> results = engine.query(state="CA", population_lower=50000, returns=10)

Note: This method maintains 100% backwards compatibility with the original API. Complex demographic queries are simplified but functional. For optimal performance, prefer the new direct methods like by_zipcode(), by_city(), etc.

Source code in zipsearch/boilerplate.py
def query(self, zipcode=None, prefix=None, pattern=None, city=None, state=None,
          lat=None, lng=None, radius=None, zipcode_type=None, sort_by=None,
          ascending=True, returns=None, **kwargs):
    """
    Backwards compatible query method for searching zipcode data.

    This method provides compatibility with the original zipsearch API while
    leveraging the new fast search infrastructure. It supports multiple search
    patterns and filters to find zipcodes based on various criteria.

    Args:
        zipcode (str, optional): Exact zipcode to lookup (e.g., "90210")
        prefix (str, optional): Zipcode prefix to search (e.g., "902" finds all 902xx codes)
        pattern (str, optional): Pattern to search within zipcode strings
        city (str, optional): City name to search for
        state (str, optional): State abbreviation (e.g., "CA", "NY")
        lat (float, optional): Latitude for coordinate-based search
        lng (float, optional): Longitude for coordinate-based search
        radius (float, optional): Search radius in miles (requires lat/lng)
        zipcode_type (ZipcodeTypeEnum, optional): Filter by zipcode type (STANDARD, PO_BOX, etc.)
        sort_by (str, optional): Sort criteria (e.g., SORT_BY_DIST for distance)
        ascending (bool, optional): Sort order direction. Defaults to True.
        returns (int, optional): Maximum number of results to return
        **kwargs: Additional demographic filters including:
            - population_lower (int): Minimum population threshold
            - population_upper (int): Maximum population threshold
            - median_household_income_lower (int): Minimum income threshold
            - median_household_income_upper (int): Maximum income threshold
            - median_home_value_lower (int): Minimum home value threshold
            - median_home_value_upper (int): Maximum home value threshold

    Returns:
        list[FastZipcode]: List of matching zipcode objects. Returns empty list if no matches.

    Examples:
        >>> engine = SearchEngine()
        >>> # Single zipcode lookup
        >>> results = engine.query(zipcode="90210")
        >>>
        >>> # Find all zipcodes starting with 902
        >>> results = engine.query(prefix="902")
        >>>
        >>> # Search by city and state
        >>> results = engine.query(city="Beverly Hills", state="CA")
        >>>
        >>> # Coordinate search within 10 miles
        >>> results = engine.query(lat=34.0901, lng=-118.4065, radius=10)
        >>>
        >>> # Demographic filtering
        >>> results = engine.query(state="CA", population_lower=50000, returns=10)

    Note:
        This method maintains 100% backwards compatibility with the original API.
        Complex demographic queries are simplified but functional. For optimal
        performance, prefer the new direct methods like by_zipcode(), by_city(), etc.
    """

    # Handle single zipcode lookup
    if zipcode is not None:
        result = self.by_zipcode(zipcode)
        return [result] if result else []

    # Handle prefix search
    if prefix is not None:
        return self.by_prefix(prefix)[:returns] if returns else self.by_prefix(prefix)

    # Handle pattern search (simplified - exact match on zipcode)
    if pattern is not None:
        results = []
        for zc, data in self._indices['zipcode_index'].items():
            if pattern in zc:
                results.append(data)
        return results[:returns] if returns else results

    # Handle city/state search
    if city is not None and state is not None:
        return self.by_city_and_state(city, state)
    elif city is not None:
        return self.by_city(city)[:returns] if returns else self.by_city(city)
    elif state is not None:
        return self.by_state(state)[:returns] if returns else self.by_state(state)

    # Handle coordinate search
    if lat is not None and lng is not None and radius is not None:
        return self.by_coordinates(lat, lng, radius)

    # Handle demographic filters (simplified - return first N results)
    if any(kwargs.get(k) for k in ['population_lower', 'population_upper',
                                   'median_home_value_lower', 'median_home_value_upper']):
        # For complex demographic queries, return a subset of all zipcodes
        # This is a simplified implementation - could be enhanced if needed
        all_results = list(self._indices['zipcode_index'].values())

        # Apply population filters if specified
        if 'population_lower' in kwargs and kwargs['population_lower']:
            all_results = [z for z in all_results if z.population and z.population >= kwargs['population_lower']]
        if 'population_upper' in kwargs and kwargs['population_upper']:
            all_results = [z for z in all_results if z.population and z.population <= kwargs['population_upper']]

        # Apply income filters if specified
        if 'median_household_income_lower' in kwargs and kwargs['median_household_income_lower']:
            all_results = [z for z in all_results if z.median_household_income and z.median_household_income >= kwargs['median_household_income_lower']]
        if 'median_household_income_upper' in kwargs and kwargs['median_household_income_upper']:
            all_results = [z for z in all_results if z.median_household_income and z.median_household_income <= kwargs['median_household_income_upper']]

        return all_results[:returns] if returns else all_results

    # Default: return empty list
    return []

Performance Notes

While the legacy API maintains full compatibility, consider using the new FastSearchEngine class for optimal performance:

  • Direct method calls (by_zipcode, by_city_and_state) are faster than the generic query method
  • Batch operations are available for ETL workflows
  • Simplified parameter handling reduces overhead

Examples

Basic Searches

from zipsearch import SearchEngine

search = SearchEngine()

# Single zipcode lookup
results = search.query(zipcode="90210")

# City and state search
results = search.query(city="Beverly Hills", state="CA")

# Coordinate search
results = search.query(lat=34.0901, lng=-118.4065, radius=10)

Advanced Filtering

# Demographic filtering
results = search.query(
    state="CA",
    population_lower=50000,
    population_upper=100000,
    returns=20
)

# Prefix search
results = search.query(prefix="902", returns=10)

Compatibility Notes

  • Complex demographic queries are simplified but functional
  • All original parameter names and types are supported
  • Return objects maintain identical structure and properties
  • Error handling behavior matches original implementation