docs: async def get_entity(self, entity):
          """
          Turns the given entity into a valid Telegram :tl:`User`, :tl:`Chat`
          or :tl:`Channel`. You can also pass a list or iterable of entities,
          and they will be efficiently fetched from the network.
  
          entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`):
              If a username is given, **the username will be resolved** making
              an API call every time. Resolving usernames is an expensive
              operation and will start hitting flood waits around 50 usernames
              in a short period of time.
  
              If you want to get the entity for a *cached* username, you should
              first `get_input_entity(username) <get_input_entity>` which will
              use the cache), and then use `get_entity` with the result of the
              previous call.
  
              Similar limits apply to invite links, and you should use their
              ID instead.
  
              Using phone numbers (from people in your contact list), exact
              names, integer IDs or :tl:`Peer` rely on a `get_input_entity`
              first, which in turn needs the entity to be in cache, unless
              a :tl:`InputPeer` was passed.
  
              Unsupported types will raise ``TypeError``.
  
              If the entity can't be found, ``ValueError`` will be raised.
  
          Returns:
              :tl:`User`, :tl:`Chat` or :tl:`Channel` corresponding to the
              input entity. A list will be returned if more than one was given.
          """
          single = not utils.is_list_like(entity)
          if single:
              entity = (entity,)
  
          # Group input entities by string (resolve username),
          # input users (get users), input chat (get chats) and
          # input channels (get channels) to get the most entities
          # in the less amount of calls possible.
          inputs = []
          for x in entity:
              if isinstance(x, str):
                  inputs.append(x)
              else:
                  inputs.append(await self.get_input_entity(x))
  
          users = [x for x in inputs
                   if isinstance(x, (types.InputPeerUser, types.InputPeerSelf))]
          chats = [x.chat_id for x in inputs
                   if isinstance(x, types.InputPeerChat)]
          channels = [x for x in inputs
                      if isinstance(x, types.InputPeerChannel)]
          if users:
              # GetUsersRequest has a limit of 200 per call
              tmp = []
              while users:
                  curr, users = users[:200], users[200:]
                  tmp.extend(await self(functions.users.GetUsersRequest(curr)))
              users = tmp
          if chats:  # TODO Handle chats slice?
              chats = (await self(
                  functions.messages.GetChatsRequest(chats))).chats
          if channels:
              channels = (await self(
                  functions.channels.GetChannelsRequest(channels))).chats
  
          # Merge users, chats and channels into a single dictionary
          id_entity = {
              utils.get_peer_id(x): x
              for x in itertools.chain(users, chats, channels)
          }
  
          # We could check saved usernames and put them into the users,
          # chats and channels list from before. While this would reduce
          # the amount of ResolveUsername calls, it would fail to catch
          # username changes.
          result = []
          for x in inputs:
              if isinstance(x, str):
                  result.append(await self._get_entity_from_string(x))
              elif not isinstance(x, types.InputPeerSelf):
                  result.append(id_entity[utils.get_peer_id(x)])
              else:
                  result.append(next(
                      u for u in id_entity.values()
                      if isinstance(u, types.User) and u.is_self
                  ))
  
          return result[0] if single else result