def create_annotation_classes_from_classes_json(project, classes_json, from_s3_bucket=None):
    'Creates annotation classes in project from a SuperAnnotate format\n    annotation classes.json.\n\n    :param project: project name or metadata of the project\n    :type project: str or dict\n    :param classes_json: JSON itself or path to the JSON file\n    :type classes_json: list or Pathlike (str or Path)\n    :param from_s3_bucket: AWS S3 bucket to use. If None then classes_json is in local filesystem\n    :type from_s3_bucket: str\n\n    :return: list of created annotation class metadatas\n    :rtype: list of dicts\n    '
    if (not isinstance(project, dict)):
        project = get_project_metadata(project)
    (team_id, project_id) = (project['team_id'], project['id'])
    if (not isinstance(classes_json, list)):
        logger.info('Creating annotation classes in project %s from %s.', project['name'], classes_json)
        if (from_s3_bucket is None):
            classes = json.load(open(classes_json))
        else:
            from_session = boto3.Session()
            from_s3 = from_session.resource('s3')
            file = io.BytesIO()
            from_s3_object = from_s3.Object(from_s3_bucket, classes_json)
            from_s3_object.download_fileobj(file)
            file.seek(0)
            classes = json.load(file)
    else:
        classes = classes_json
    existing_classes = search_annotation_classes(project)
    new_classes = []
    for cs in classes:
        if (cs['name'] in existing_classes):
            logger.warning('Annotation class %s already in project. Skipping.', cs['name'])
        else:
            new_classes.append(cs)
    res = []

    def del_unn(d):
        for s in ['updatedAt', 'createdAt', 'id', 'project_id', 'group_id', 'class_id', 'count']:
            if (s in d):
                del d[s]
    for annotation_class in new_classes:
        del_unn(annotation_class)
        for attribute_group in annotation_class['attribute_groups']:
            del_unn(attribute_group)
            for attribute in attribute_group['attributes']:
                del_unn(attribute)
    CHUNK_SIZE = 2000
    for i in range(0, len(new_classes), CHUNK_SIZE):
        params = {'team_id': team_id, 'project_id': project_id}
        data = {'classes': new_classes[i:(i + CHUNK_SIZE)]}
        response = _api.send_request(req_type='POST', path='/classes', params=params, json_req=data)
        if (not response.ok):
            raise SABaseException(response.status_code, ("Couldn't create classes " + response.text))
        res += response.json()
    assert (len(res) == len(new_classes))
    return res
Creates annotation classes in project from a SuperAnnotate format
annotation classes.json.

:param project: project name or metadata of the project
:type project: str or dict
:param classes_json: JSON itself or path to the JSON file
:type classes_json: list or Pathlike (str or Path)
:param from_s3_bucket: AWS S3 bucket to use. If None then classes_json is in local filesystem
:type from_s3_bucket: str

:return: list of created annotation class metadatas
:rtype: list of dicts
def create_annotation_classes_from_classes_json(project, classes_json, from_s3_bucket=None):
    'Creates annotation classes in project from a SuperAnnotate format\n    annotation classes.json.\n\n    :param project: project name or metadata of the project\n    :type project: str or dict\n    :param classes_json: JSON itself or path to the JSON file\n    :type classes_json: list or Pathlike (str or Path)\n    :param from_s3_bucket: AWS S3 bucket to use. If None then classes_json is in local filesystem\n    :type from_s3_bucket: str\n\n    :return: list of created annotation class metadatas\n    :rtype: list of dicts\n    '
    if (not isinstance(project, dict)):
        project = get_project_metadata(project)
    (team_id, project_id) = (project['team_id'], project['id'])
    if (not isinstance(classes_json, list)):
        logger.info('Creating annotation classes in project %s from %s.', project['name'], classes_json)
        if (from_s3_bucket is None):
            classes = json.load(open(classes_json))
        else:
            from_session = boto3.Session()
            from_s3 = from_session.resource('s3')
            file = io.BytesIO()
            from_s3_object = from_s3.Object(from_s3_bucket, classes_json)
            from_s3_object.download_fileobj(file)
            file.seek(0)
            classes = json.load(file)
    else:
        classes = classes_json
    existing_classes = search_annotation_classes(project)
    new_classes = []
    for cs in classes:
        if (cs['name'] in existing_classes):
            logger.warning('Annotation class %s already in project. Skipping.', cs['name'])
        else:
            new_classes.append(cs)
    res = []

    def del_unn(d):
        for s in ['updatedAt', 'createdAt', 'id', 'project_id', 'group_id', 'class_id', 'count']:
            if (s in d):
                del d[s]
    for annotation_class in new_classes:
        del_unn(annotation_class)
        for attribute_group in annotation_class['attribute_groups']:
            del_unn(attribute_group)
            for attribute in attribute_group['attributes']:
                del_unn(attribute)
    CHUNK_SIZE = 2000
    for i in range(0, len(new_classes), CHUNK_SIZE):
        params = {'team_id': team_id, 'project_id': project_id}
        data = {'classes': new_classes[i:(i + CHUNK_SIZE)]}
        response = _api.send_request(req_type='POST', path='/classes', params=params, json_req=data)
        if (not response.ok):
            raise SABaseException(response.status_code, ("Couldn't create classes " + response.text))
        res += response.json()
    assert (len(res) == len(new_classes))
    return res