code: def federation(address_or_id, fed_type='name', domain=None, allow_http=False):
      
      if fed_type == 'name':
          if '*' not in address_or_id:
              raise FederationError('Not a valid federation address.')
  
          param, domain = address_or_id.rsplit('*', 1)
          if param == '' or domain == '':
              raise FederationError('Not a valid federation address.')
      elif fed_type == 'id':
          try:
              assert is_valid_address(address_or_id)
          except StellarAddressInvalidError:
              raise FederationError('{} is not a valid account id.'.format(address_or_id))
      else:
          raise FederationError('Not a valid fed_type.')
  
      if '.' not in domain:
          raise FederationError('Not a valid domain name.')
      fed_service = get_federation_service(domain, allow_http)
      if not fed_service:
          raise FederationError('Not a valid federation server.')
  
      return _get_federation_info(address_or_id, fed_service, fed_type)
docs: Send a federation query to a Stellar Federation service.
  
      For more info, see the `complete guide on Stellar Federation.
      <https://www.stellar.org/developers/guides/concepts/federation.html>`_.
  
      :param str address_or_id: The address which you expect te retrieve
          federation information about.
      :param str fed_type: The type of federation query that you are making. Must
          be 'name', 'id', 'forward', or 'txid'.
      :param str domain: The domain that corresponds to the address or ID;
          this is where the stellar.toml file lives (which ultimately points to
          the URL of the federation service).
      :param bool allow_http: Whether to allow for requests over plain HTTP over
          HTTPS. Note - you should *always* use HTTPS outside of testing.
      :return dict: The federation query response decoded from JSON as a dict.