def features_from_polygon(
    polygon: Polygon | MultiPolygon,
    tags: dict[str, bool | str | list[str]],
) -> gpd.GeoDataFrame:
    """
    Download OSM features within the boundaries of a (Multi)Polygon.

    You can use the `settings` module to retrieve a snapshot of historical OSM
    data as of a certain date, or to configure the Overpass server timeout,
    memory allocation, and other custom settings. This function searches for
    features using tags. For more details, see:
    https://wiki.openstreetmap.org/wiki/Map_features

    Parameters
    ----------
    polygon
        The geometry within which to retrieve features. Coordinates should be
        in unprojected latitude-longitude degrees (EPSG:4326).
    tags
        Tags for finding elements in the selected area. Results are the union,
        not intersection of the tags and each result matches at least one tag.
        The keys are OSM tags (e.g. `building`, `landuse`, `highway`, etc) and
        the values can be either `True` to retrieve all elements matching the
        tag, or a string to retrieve a single `tag:value` combination, or a
        list of strings to retrieve multiple values for the tag. For example,
        `tags = {'building': True}` would return all buildings in the area.
        Or, `tags = {'amenity':True, 'landuse':['retail','commercial'],
        'highway':'bus_stop'}` would return all amenities, any landuse=retail,
        any landuse=commercial, and any highway=bus_stop.

    Returns
    -------
    gdf
        The features, multi-indexed by element type and OSM ID.
    """
    # verify that the geometry is valid and is a Polygon/MultiPolygon
    if not polygon.is_valid:
        msg = "The geometry of `polygon` is invalid."
        raise ValueError(msg)

    if not isinstance(polygon, (Polygon, MultiPolygon)):
        msg = (
            "Boundaries must be a Polygon or MultiPolygon. If you requested "
            "`features_from_place`, ensure your query geocodes to a Polygon "
            "or MultiPolygon. See the documentation for details."
        )
        raise TypeError(msg)

    # retrieve the data from Overpass then turn it into a GeoDataFrame
    response_jsons = _overpass._download_overpass_features(polygon, tags)
    return _create_gdf(response_jsons, polygon, tags)

    Download OSM features within the boundaries of a (Multi)Polygon.

    You can use the `settings` module to retrieve a snapshot of historical OSM
    data as of a certain date, or to configure the Overpass server timeout,
    memory allocation, and other custom settings. This function searches for
    features using tags. For more details, see:
    https://wiki.openstreetmap.org/wiki/Map_features

    Parameters
    ----------
    polygon
        The geometry within which to retrieve features. Coordinates should be
        in unprojected latitude-longitude degrees (EPSG:4326).
    tags
        Tags for finding elements in the selected area. Results are the union,
        not intersection of the tags and each result matches at least one tag.
        The keys are OSM tags (e.g. `building`, `landuse`, `highway`, etc) and
        the values can be either `True` to retrieve all elements matching the
        tag, or a string to retrieve a single `tag:value` combination, or a
        list of strings to retrieve multiple values for the tag. For example,
        `tags = {'building': True}` would return all buildings in the area.
        Or, `tags = {'amenity':True, 'landuse':['retail','commercial'],
        'highway':'bus_stop'}` would return all amenities, any landuse=retail,
        any landuse=commercial, and any highway=bus_stop.

    Returns
    -------
    gdf
        The features, multi-indexed by element type and OSM ID.
    
osmnx/features.py