def fan_in_out_capacities(topology):
    """Calculate fan-in and fan-out capacities for all nodes of the topology.

    The fan-in capacity of a node is the sum of capacities of all incoming
    links, while the fan-out capacity is the sum of capacities of all outgoing
    links.

    Parameters
    ----------
    topology : Topology
        The topology object whose fan-in and fan-out capacities are calculated.
        This topology must be annotated with link capacities.

    Returns
    -------
    fan_in_out_capacities : tuple (fan_in, fan_out)
        A tuple of two dictionaries, representing, respectively the fan-in and
        fan-out capacities keyed by node.

    Notes
    -----
    This function works correctly for both directed and undirected topologies.
    If the topology is undirected, the returned dictionaries of fan-in and
    fan-out capacities are identical.

    Examples
    --------
    >>> import fnss
    >>> topology = fnss.star_topology(3)
    >>> fnss.set_capacities_constant(topology, 10, 'Mbps')
    >>> in_cap, out_cap = fnss.fan_in_out_capacities(topology)
    >>> in_cap
    {0: 30, 1: 10, 2: 10, 3: 10}
    >>> out_cap
    {0: 30, 1: 10, 2: 10, 3: 10}
    """
    if not topology.is_directed():
        topology = topology.to_directed()
    fan_in = {}
    fan_out = {}
    for node in topology.nodes():
        node_fan_in = 0
        node_fan_out = 0
        for predecessor in topology.predecessors(node):
            node_fan_in += topology.adj[predecessor][node]['capacity']
        for successor in topology.successors(node):
            node_fan_out += topology.adj[node][successor]['capacity']
        fan_in[node] = node_fan_in
        fan_out[node] = node_fan_out
    return fan_in, fan_out
