docs: def where(cls, *filters, **keyword_filters):
          """Retrieves objects (Samples, Classifications, etc.) from the One Codex server.
  
          Parameters
          ----------
          filters : objects
              Advanced filters to use (not implemented)
          sort : string | list, optional
              Sort the results by this field (or list of fields). By default in descending order,
              but if any of the fields start with the special character ^, sort in ascending order.
              For example, sort=['size', '^filename'] will sort by size from largest to smallest and
              filename from A-Z for items with the same size.
          limit : integer, optional
              Number of records to return. For smaller searches, this can reduce the number of
              network requests made.
          keyword_filters : strings | objects
              Filter the results by specific keywords (or filter objects, in advanced usage)
  
          Examples
          --------
          You can filter objects that are returned locally using a lambda function:
  
              # returns only samples with a filename ending in '.gz'
              my_samples = Samples.where(filter=lambda s: s.filename.endswith('.gz'))
  
          Returns
          -------
          list
              A list of all objects matching these filters. If no filters are passed, this
              matches all objects.
          """
          check_bind(cls)
  
          # do this here to avoid passing this on to potion
          filter_func = keyword_filters.pop("filter", None)
  
          public = False
          if any(x["rel"] == "instances_public" for x in cls._resource._schema["links"]):
              public = keyword_filters.pop("public", False)
  
          instances_route = keyword_filters.pop(
              "_instances", "instances" if not public else "instances_public"
          )
  
          schema = next(l for l in cls._resource._schema["links"] if l["rel"] == instances_route)
          sort_schema = schema["schema"]["properties"]["sort"]["properties"]
          where_schema = schema["schema"]["properties"]["where"]["properties"]
  
          sort = generate_potion_sort_clause(keyword_filters.pop("sort", None), sort_schema)
          limit = keyword_filters.pop("limit", None if not public else 1000)
          where = {}
  
          # we're filtering by fancy objects (like SQLAlchemy's filter)
          if len(filters) > 0:
              if len(filters) == 1 and isinstance(filters[0], dict):
                  where = filters[0]
              elif all(isinstance(f, six.string_types) for f in filters):
                  # if it's a list of strings, treat it as an multiple "get" request
                  where = {"$uri": {"$in": [cls._convert_id_to_uri(f) for f in filters]}}
              else:
                  # we're doing some more advanced filtering
                  raise NotImplementedError("Advanced filtering hasn't been implemented yet")
  
          # we're filtering by keyword arguments (like SQLAlchemy's filter_by)
          if len(keyword_filters) > 0:
              for k, v in generate_potion_keyword_where(keyword_filters, where_schema, cls).items():
                  if k in where:
                      raise AttributeError("Multiple definitions for same field {}".format(k))
                  where[k] = v
  
          # the potion-client method returns an iterator (which lazily fetchs the records
          # using `per_page` instances per request) so for limiting we only want to fetch the first
          # n (and not instantiate all the available which is what would happen if we just sliced)
          cursor = getattr(cls._resource, instances_route)(
              where=where, sort=sort, per_page=DEFAULT_PAGE_SIZE
          )
          if limit is not None:
              cursor = itertools.islice(cursor, limit)
  
          # finally, apply local filtering function on objects before returning
          wrapped = [cls(_resource=r) for r in cursor]
  
          if filter_func:
              if callable(filter_func):
                  wrapped = [obj for obj in wrapped if filter_func(obj) is True]
              else:
                  raise OneCodexException(
                      "Expected callable for filter, got: {}".format(type(filter_func).__name__)
                  )
  
          return wrapped