code: def search(query, medium, credentials):
      
      helpers.check_creds(credentials, header)
      if len(query) == 0:
          raise ValueError(constants.INVALID_EMPTY_QUERY)
      api_query = helpers.get_query_url(medium, query)
      if api_query is None:
          raise ValueError(constants.INVALID_MEDIUM)
      search_resp = requests.get(api_query, auth=credentials, headers=header)
      if search_resp is None or search_resp.status_code == 204: # is there a better way to do this...
          return []
      query_soup = BeautifulSoup(search_resp.text, 'lxml')
      if medium == tokens.Medium.ANIME:
          entries = query_soup.anime
          if entries is None:
              return helpers.reschedule(search, constants.DEFAULT_WAIT_SECS, query,
                                        medium, credentials)
  
          return [objects.Anime(entry) for entry in entries.findAll('entry')]
      elif medium == tokens.Medium.MANGA:
          entries = query_soup.manga
          if entries is None:
              return helpers.reschedule(search, constants.DEFAULT_WAIT_SECS, query,
                                        medium)
          return [objects.Manga(entry) for entry in entries.findAll('entry')]
docs: Searches MyAnimeList for a [medium] matching the keyword(s) given by query.
      :param query  The keyword(s) to search with.
      :param medium Anime or manga (tokens.Medium.ANIME or tokens.Medium.MANGA).
      :return A list of all items that are of type [medium] and match the
               given keywords, or, an empty list if none matched.
      :raise ValueError For bad arguments.