hyperion/models/util.py
async def get_bikes(postcode: PostCodeLike, kilometers=1) -> Optional[List[Bike]]:
    """
    Gets stolen bikes from the database within a
    certain radius (km) of a given postcode. Selects
    a square from the database and then filters out
    the corners of the square.
    :param postcode: The postcode to look up.
    :param kilometers: The radius (km) of the search.
    :return: The bikes in that radius or None if the postcode doesn't exist.
    """

    try:
        postcode_opt = await get_postcode(postcode)
    except CachingError as e:
        raise e

    if postcode_opt is None:
        return None
    else:
        postcode = postcode_opt

    # create point and distance
    center = Point(postcode.lat, postcode.long)
    distance = geodesic(kilometers=kilometers)

    # calculate edges of a square and retrieve
    lat_end = distance.destination(point=center, bearing=0).latitude
    lat_start = distance.destination(point=center, bearing=180).latitude
    long_start = distance.destination(point=center, bearing=270).longitude
    long_end = distance.destination(point=center, bearing=90).longitude

    bikes_in_area = Bike.select().where(
        lat_start <= Bike.latitude,
        Bike.latitude <= lat_end,
        long_start <= Bike.longitude,
        Bike.longitude <= long_end
    )

    # filter out items in square that aren't within the radius and return
    return [
        bike for bike in bikes_in_area
        if geodesic(Point(bike.latitude, bike.longitude), center).kilometers < kilometers
    ]
async def get_bikes(postcode: PostCodeLike, kilometers=1) -> Optional[List[Bike]]:
    """
    Gets stolen bikes from the database within a
    certain radius (km) of a given postcode. Selects
    a square from the database and then filters out
    the corners of the square.
    :param postcode: The postcode to look up.
    :param kilometers: The radius (km) of the search.
    :return: The bikes in that radius or None if the postcode doesn't exist.
    """

    try:
        postcode_opt = await get_postcode(postcode)
    except CachingError as e:
        raise e

    if postcode_opt is None:
        return None
    else:
        postcode = postcode_opt

    # create point and distance
    center = Point(postcode.lat, postcode.long)
    distance = geodesic(kilometers=kilometers)

    # calculate edges of a square and retrieve
    lat_end = distance.destination(point=center, bearing=0).latitude
    lat_start = distance.destination(point=center, bearing=180).latitude
    long_start = distance.destination(point=center, bearing=270).longitude
    long_end = distance.destination(point=center, bearing=90).longitude

    bikes_in_area = Bike.select().where(
        lat_start <= Bike.latitude,
        Bike.latitude <= lat_end,
        long_start <= Bike.longitude,
        Bike.longitude <= long_end
    )

    # filter out items in square that aren't within the radius and return
    return [
        bike for bike in bikes_in_area
        if geodesic(Point(bike.latitude, bike.longitude), center).kilometers < kilometers
    ]
Gets stolen bikes from the database within a
    certain radius (km) of a given postcode. Selects
    a square from the database and then filters out
    the corners of the square.
    :param postcode: The postcode to look up.
    :param kilometers: The radius (km) of the search.
    :return: The bikes in that radius or None if the postcode doesn't exist.