Splitting up a list with datetimes
It is possible to utilize itertools.groupby() using indexes to calculate if there is a gap:

import datetime
from datetime import timedelta
from functools import partial
from itertools import groupby
from operator import itemgetter


def is_consecutive(start_date, item):
    """A grouping key function that highlights the gaps in a list of datetimes with a 30 minute interval."""
    index, value = item
    return (start_date + index * timedelta(minutes=30)) - value


available = [
    datetime.datetime(2010, 1, 1, 9, 0),
    datetime.datetime(2010, 1, 1, 9, 30),
    datetime.datetime(2010, 1, 1, 10, 0),
    datetime.datetime(2010, 1, 1, 10, 30),
    datetime.datetime(2010, 1, 1, 13, 0),  # gap
    datetime.datetime(2010, 1, 1, 13, 30),
    datetime.datetime(2010, 1, 1, 15, 30),  # gap
    datetime.datetime(2010, 1, 1, 16, 0),
    datetime.datetime(2010, 1, 1, 16, 30)
]

start_date = available[0]

result = []
for _, group in groupby(enumerate(available), key=partial(is_consecutive, start_date)):
    current_range = list(map(itemgetter(1), group))

    result.append({
        'start': current_range[0],
        'end': current_range[-1]
    })
print(result)


Prints:

[
    {'start': datetime.datetime(2010, 1, 1, 9, 0), 'end': datetime.datetime(2010, 1, 1, 10, 30)}, 
    {'start': datetime.datetime(2010, 1, 1, 13, 0), 'end': datetime.datetime(2010, 1, 1, 13, 30)}, 
    {'start': datetime.datetime(2010, 1, 1, 15, 30), 'end': datetime.datetime(2010, 1, 1, 16, 30)}
]