    def get(self):
        """List groups"""
        query = full_query = self.db.query(orm.Group)
        sub_scope = self.parsed_scopes['list:groups']
        if sub_scope != Scope.ALL:
            if not set(sub_scope).issubset({'group'}):
                # the only valid filter is group=...
                # don't expand invalid !server=x to all groups!
                self.log.warning(
                    f"Invalid filter on list:group for {self.current_user}: {sub_scope}"
                )
                raise web.HTTPError(403)
            query = query.filter(orm.Group.name.in_(sub_scope['group']))

        offset, limit = self.get_api_pagination()
        query = query.order_by(orm.Group.id.asc()).offset(offset).limit(limit)
        group_list = [self.group_model(g) for g in query]
        total_count = full_query.count()
        if self.accepts_pagination:
            data = self.paginated_model(group_list, offset, limit, total_count)
        else:
            query_count = query.count()
            if offset == 0 and total_count > query_count:
                self.log.warning(
                    f"Truncated group list in request that does not expect pagination. Replying with {query_count} of {total_count} total groups."
                )
            data = group_list
        self.write(json.dumps(data))
List groups
jupyterhub/apihandlers/groups.py