Exemple #1
0
def test_folder_export(tmpdir):
    PROJECT_NAME = "test folder export"
    tmpdir = Path(tmpdir)

    projects_found = sa.search_projects(PROJECT_NAME, return_metadata=True)
    for pr in projects_found:
        sa.delete_project(pr)

    project = sa.create_project(PROJECT_NAME, 'test', 'Vector')
    sa.create_annotation_classes_from_classes_json(
        project, FROM_FOLDER / "classes" / "classes.json")
    sa.upload_images_from_folder_to_project(project,
                                            FROM_FOLDER,
                                            annotation_status="InProgress")
    sa.create_folder(project, "folder1")
    project = PROJECT_NAME + "/folder1"
    sa.upload_images_from_folder_to_project(project,
                                            FROM_FOLDER,
                                            annotation_status="InProgress")

    sa.upload_annotations_from_folder_to_project(project, FROM_FOLDER)
    num_images = sa.get_project_image_count(project)
    assert num_images == 4

    sa.create_folder(PROJECT_NAME, "folder2")
    project2 = PROJECT_NAME + "/folder2"
    num_images = sa.get_project_image_count(project2)
    assert num_images == 0

    sa.copy_images(project, ["example_image_2.jpg", "example_image_3.jpg"],
                   project2)

    export = sa.prepare_export(PROJECT_NAME, ["folder1", "folder2"])
    sa.download_export(project, export, tmpdir)

    assert len(list((tmpdir / "classes").rglob("*"))) == 1

    assert len(list((tmpdir / "folder1").rglob("*"))) == 4

    assert len(list((tmpdir / "folder2").rglob("*"))) == 2

    assert len(list((tmpdir).glob("*.*"))) == 0

    export = sa.prepare_export(PROJECT_NAME)
    sa.download_export(project, export, tmpdir)

    assert len(list((tmpdir / "classes").rglob("*"))) == 1

    assert len(list((tmpdir / "folder1").rglob("*"))) == 4

    assert len(list((tmpdir / "folder2").rglob("*"))) == 2

    assert len(list((tmpdir).glob("*.*"))) == 4
Exemple #2
0
def test_add_bbox_noinit(tmpdir):
    tmpdir = Path(tmpdir)

    projects_found = sa.search_projects(
        PROJECT_NAME_NOINIT, return_metadata=True
    )
    for pr in projects_found:
        sa.delete_project(pr)

    project = sa.create_project(
        PROJECT_NAME_NOINIT, PROJECT_DESCRIPTION, "Vector"
    )
    sa.upload_images_from_folder_to_project(
        project, PATH_TO_SAMPLE_PROJECT, annotation_status="InProgress"
    )
    sa.create_annotation_classes_from_classes_json(
        project, PATH_TO_SAMPLE_PROJECT / "classes" / "classes.json"
    )
    sa.create_annotation_class(project, "test_add", "#FF0000")
    images = sa.search_images(project, "example_image_1")

    image_name = images[0]
    sa.add_annotation_bbox_to_image(
        project, image_name, [10, 10, 500, 100], "test_add"
    )
    sa.add_annotation_polygon_to_image(
        project, image_name, [100, 100, 500, 500, 200, 300], "test_add"
    )
    annotations_new = sa.get_image_annotations(project,
                                               image_name)["annotation_json"]

    assert len(annotations_new) == 2
    export = sa.prepare_export(project, include_fuse=True)
    sa.download_export(project, export, tmpdir)
    assert len(list(Path(tmpdir).rglob("*.*"))) == 4
Exemple #3
0
def export_project(args):
    parser = argparse.ArgumentParser()
    parser.add_argument('--project',
                        required=True,
                        help='Project name to export')
    parser.add_argument('--folder',
                        required=True,
                        help='Folder to which export')
    parser.add_argument('--include-fuse',
                        default=False,
                        action='store_true',
                        help='Enables fuse image export')
    parser.add_argument('--disable-extract-zip-contents',
                        default=False,
                        action='store_true',
                        help='Disables export zip extraction')
    parser.add_argument(
        '--annotation-statuses',
        default=None,
        type=_list_str,
        help=
        'List of image annotation statuses to include in export. Default is InProgress,QualityCheck,Returned,Completed'
    )
    args = parser.parse_args(args)

    export = sa.prepare_export(args.project, args.annotation_statuses,
                               args.include_fuse)
    sa.download_export(args.project, export, args.folder,
                       not args.disable_extract_zip_contents)
def test_recursive_annotations_folder(tmpdir):
    tmpdir = Path(tmpdir)
    projects_found = sa.search_projects(
        TEMP_PROJECT_NAME + "1", return_metadata=True
    )
    for pr in projects_found:
        sa.delete_project(pr)

    project = sa.create_project(TEMP_PROJECT_NAME + "1", "test", "Vector")

    sa.upload_images_from_folder_to_project(
        project,
        "./tests/sample_recursive_test",
        annotation_status="QualityCheck",
        recursive_subfolders=True
    )

    assert len(sa.search_images(project)) == 2

    sa.create_annotation_classes_from_classes_json(
        project, "./tests/sample_recursive_test/classes/classes.json"
    )

    sa.upload_annotations_from_folder_to_project(
        project, "./tests/sample_recursive_test", recursive_subfolders=True
    )

    export = sa.prepare_export(project)

    time.sleep(1)
    sa.download_export(project, export, tmpdir)

    assert len(list(tmpdir.glob("*.json"))) == 2
Exemple #5
0
def test_basic_export(tmpdir):
    tmpdir = Path(tmpdir)

    projects_found = sa.search_projects(PROJECT_NAME, return_metadata=True)
    for pr in projects_found:
        sa.delete_project(pr)

    project = sa.create_project(PROJECT_NAME, "t", "Vector")
    sa.upload_images_from_folder_to_project(
        project, PROJECT_FOLDER, annotation_status="InProgress"
    )
    len_orig = len(sa.search_images(project))

    sa.create_annotation_classes_from_classes_json(
        project, PROJECT_FOLDER / "classes" / "classes.json"
    )
    sa.upload_annotations_from_folder_to_project(project, PROJECT_FOLDER)

    export = sa.prepare_export(project, include_fuse=True)

    sa.download_export(project, export, tmpdir)

    projects_found = sa.search_projects(
        PROJECT_NAME + " import", return_metadata=True
    )
    for pr in projects_found:
        sa.delete_project(pr)
    project_new = sa.create_project(PROJECT_NAME + " import", "f", "Vector")
    sa.upload_images_from_folder_to_project(
        project_new, tmpdir, annotation_status="InProgress"
    )
    len_new = len(sa.search_images(project_new))

    assert len_new == len_orig
def test_get_exports(tmpdir):
    tmpdir = Path(tmpdir)
    project = upload_project(PROJECT_FOLDER,
                             PROJECT_NAME1,
                             'gg',
                             'Vector',
                             annotation_status='QualityCheck')
    # projects_found = sa.search_projects(PROJECT_NAME1, return_metadata=True)
    # for pr in projects_found:
    #     sa.delete_project(pr)
    # project = sa.create_project(PROJECT_NAME1, "gg", "Vector")
    # sa.upload_images_from_folder_to_project(
    #     project,
    #     "./tests/sample_project_vector/",
    #     annotation_status="QualityCheck"
    # )
    # sa.create_annotation_classes_from_classes_json(
    #     project,
    #     "./tests/sample_project_vector/classes/classes.json",
    # )
    # sa.upload_annotations_from_folder_to_project(
    #     project,
    #     "./tests/sample_project_vector/",
    # )
    exports_old = sa.get_exports(project)

    export = sa.prepare_export(project)
    sa.download_export(project, export["name"], tmpdir)
    js = list(tmpdir.glob("*.json"))

    assert len(js) == 4

    exports_new = sa.get_exports(project)

    assert len(exports_new) == len(exports_old) + 1
Exemple #7
0
def test_download_stress(tmpdir):
    project = sa.search_projects(name_prefix="test_test_15")[0]
    export = sa.prepare_export(project)
    sa.download_export(project, export, tmpdir)

    count_in_project = sa.get_project_image_count(project)
    count_in_folder = len(list(Path(tmpdir).glob("*.jpg")))

    assert count_in_project == count_in_folder
Exemple #8
0
def sa_download_files(
    project_name: str,
    destination: str = "./downloads",
    conf_path: object = "./config.json",
):

    sa.init(conf_path)

    export = sa.prepare_export(project_name, include_fuse=True)

    sa.download_export(project=project_name,
                       export=export,
                       folder_path=destination)
def test_export_s3(tmpdir):
    paginator = s3_client.get_paginator('list_objects_v2')
    response_iterator = paginator.paginate(Bucket=S3_BUCKET, Prefix=S3_PREFIX2)
    for response in response_iterator:
        if 'Contents' in response:
            for object_data in response['Contents']:
                key = object_data['Key']
                s3_client.delete_object(Bucket=S3_BUCKET, Key=key)
    tmpdir = Path(tmpdir)

    project = upload_project(Path("./tests/sample_project_vector"),
                             PROJECT_NAME_EXPORT,
                             'test',
                             'Vector',
                             annotation_status='InProgress')
    # projects = sa.search_projects(PROJECT_NAME_EXPORT, return_metadata=True)
    # for project in projects:
    #     sa.delete_project(project)
    # project = sa.create_project(PROJECT_NAME_EXPORT, "test", "Vector")

    # sa.upload_images_from_folder_to_project(
    #     project,
    #     Path("./tests/sample_project_vector"),
    #     annotation_status="InProgress"
    # )
    # sa.create_annotation_classes_from_classes_json(
    #     project, Path("./tests/sample_project_vector/classes/classes.json")
    # )
    # sa.upload_annotations_from_folder_to_project(
    #     project, Path("./tests/sample_project_vector")
    # )
    images = sa.search_images(project)
    for img in images:
        sa.set_image_annotation_status(project, img, 'QualityCheck')

    new_export = sa.prepare_export(project, include_fuse=True)
    sa.download_export(project, new_export, S3_PREFIX2, to_s3_bucket=S3_BUCKET)

    files = []
    response_iterator = paginator.paginate(Bucket=S3_BUCKET, Prefix=S3_PREFIX2)
    for response in response_iterator:
        if 'Contents' in response:
            for object_data in response['Contents']:
                key = object_data['Key']
                files.append(key)
    output_path = tmpdir / S3_PREFIX2
    output_path.mkdir()
    sa.download_export(project, new_export, output_path)
    local_files = list(output_path.rglob("*.*"))

    assert len(local_files) == len(files)
def test_fuse_image_create_pixel(tmpdir):
    tmpdir = Path(tmpdir)

    projects = sa.search_projects(PROJECT_NAME_PIXEL, return_metadata=True)
    for project in projects:
        sa.delete_project(project)

    project = sa.create_project(PROJECT_NAME_PIXEL, "test", "Pixel")

    sa.upload_image_to_project(
        project,
        "./tests/sample_project_pixel/example_image_1.jpg",
        annotation_status="QualityCheck"
    )

    sa.create_annotation_classes_from_classes_json(
        project, "./tests/sample_project_pixel/classes/classes.json"
    )
    sa.upload_image_annotations(
        PROJECT_NAME_PIXEL, "example_image_1.jpg",
        "./tests/sample_project_pixel/example_image_1.jpg___pixel.json",
        "./tests/sample_project_pixel/example_image_1.jpg___save.png"
    )

    export = sa.prepare_export(project, include_fuse=True)
    (tmpdir / "export").mkdir()
    sa.download_export(project, export, (tmpdir / "export"))

    # sa.create_fuse_image(
    #     "./tests/sample_project_vector/example_image_1.jpg",
    #     "./tests/sample_project_vector/classes/classes.json", "Vector"
    # )

    paths = sa.download_image(
        project,
        "example_image_1.jpg",
        tmpdir,
        include_annotations=True,
        include_fuse=True
    )
    print(paths, paths[2])
    im1 = Image.open(tmpdir / "export" / "example_image_1.jpg___fuse.png")
    im1_array = np.array(im1)

    im2 = Image.open(paths[2][0])
    im2_array = np.array(im2)

    assert im1_array.shape == im2_array.shape
    assert im1_array.dtype == im2_array.dtype
    assert np.array_equal(im1_array, im2_array)
def test_annotations_nonrecursive_s3_folder(tmpdir):
    tmpdir = Path(tmpdir)
    projects_found = sa.search_projects(
        TEMP_PROJECT_NAME + "5", return_metadata=True
    )
    for pr in projects_found:
        sa.delete_project(pr)

    project = sa.create_project(TEMP_PROJECT_NAME + "5", "test", "Vector")

    sa.upload_images_from_folder_to_project(
        project,
        "sample_recursive_test",
        annotation_status="QualityCheck",
        from_s3_bucket="superannotate-python-sdk-test",
        recursive_subfolders=True
    )

    assert len(sa.search_images(project)) == 2

    sa.create_annotation_classes_from_classes_json(
        project,
        "sample_recursive_test/classes/classes.json",
        from_s3_bucket="superannotate-python-sdk-test"
    )

    sa.upload_annotations_from_folder_to_project(
        project,
        "sample_recursive_test",
        recursive_subfolders=False,
        from_s3_bucket="superannotate-python-sdk-test"
    )

    export = sa.prepare_export(project)

    time.sleep(1)
    sa.download_export(project, export, tmpdir)

    non_empty_annotations = 0
    json_files = tmpdir.glob("*.json")
    for json_file in json_files:
        json_ann = json.load(open(json_file))
        if "instances" in json_ann and len(json_ann["instances"]) > 0:
            non_empty_annotations += 1

    assert non_empty_annotations == 1
Exemple #12
0
def export_project(command_name, args):
    parser = argparse.ArgumentParser(prog=_CLI_COMMAND + " " + command_name)
    parser.add_argument('--project',
                        required=True,
                        help='Project name to export')
    parser.add_argument('--folder',
                        required=True,
                        help='Folder to which export')
    parser.add_argument('--include-fuse',
                        default=False,
                        action='store_true',
                        help='Enables fuse image export')
    parser.add_argument('--disable-extract-zip-contents',
                        default=False,
                        action='store_true',
                        help='Disables export zip extraction')
    parser.add_argument(
        '--annotation-statuses',
        default=None,
        type=_list_str,
        help=
        'List of image annotation statuses to include in export. Default is InProgress,QualityCheck,Returned,Completed'
    )
    args = parser.parse_args(args)

    parts = args.project.split('/')
    if len(parts) == 1:
        project, project_folder = parts[0], None
    elif len(parts) == 2:
        project, project_folder = parts
    else:
        raise SABaseException(
            0, "Project should be in format <project>[/<folder>]")
    export = sa.prepare_export(
        project,
        None if project_folder is None else [project_folder],
        annotation_statuses=args.annotation_statuses,
        include_fuse=args.include_fuse)
    sa.download_export(args.project, export, args.folder,
                       not args.disable_extract_zip_contents)
Exemple #13
0
def test_add_bbox_noinit(tmpdir):
    tmpdir = Path(tmpdir)

    projects_found = sa.search_projects(PROJECT_NAME_NOINIT,
                                        return_metadata=True)
    for pr in projects_found:
        sa.delete_project(pr)

    project = sa.create_project(PROJECT_NAME_NOINIT, PROJECT_DESCRIPTION,
                                "Vector")
    sa.upload_images_from_folder_to_project(project,
                                            PATH_TO_SAMPLE_PROJECT,
                                            annotation_status="InProgress")
    sa.create_annotation_classes_from_classes_json(
        project, PATH_TO_SAMPLE_PROJECT / "classes" / "classes.json")
    sa.create_annotation_class(project, "test_add", "#FF0000")
    images = sa.search_images(project, "example_image_1")

    image_name = images[0]
    sa.add_annotation_bbox_to_image(project, image_name, [10, 10, 500, 100],
                                    "test_add")
    sa.add_annotation_polygon_to_image(project, image_name,
                                       [100, 100, 500, 500, 200, 300],
                                       "test_add")
    annotations_new = sa.get_image_annotations(project,
                                               image_name)["annotation_json"]

    assert len(annotations_new["instances"]) == 2
    export = sa.prepare_export(project, include_fuse=True)
    sa.download_export(project, export, tmpdir)

    non_empty_annotations = 0
    json_files = tmpdir.glob("*.json")
    for json_file in json_files:
        json_ann = json.load(open(json_file))
        if "instances" in json_ann and len(json_ann["instances"]) > 0:
            non_empty_annotations += 1
            assert len(json_ann["instances"]) == 2

    assert non_empty_annotations == 1
Exemple #14
0
def test_meta_init(tmpdir):
    projects = sa.search_projects(name, return_metadata=True)
    for project in projects:
        sa.delete_project(project)

    project = sa.create_project(name, description, project_type)

    sa.upload_images_from_folder_to_project(project,
                                            from_folder,
                                            annotation_status="InProgress")

    for image in from_folder.glob("*.jpg"):
        size = cv2.imread(str(image)).shape
        annot = sa.get_image_annotations(project,
                                         image.name)["annotation_json"]
        print(annot)
        assert annot["metadata"]["width"] == size[1]
        assert annot["metadata"]["height"] == size[0]
        assert annot["metadata"]["name"] == image.name
        assert len(annot["metadata"]) == 3

    sa.download_export(project, sa.prepare_export(project), tmpdir)
Exemple #15
0
def test_get_exports(tmpdir):
    tmpdir = Path(tmpdir)

    projects_found = sa.search_projects(PROJECT_NAME, return_metadata=True)
    for pr in projects_found:
        sa.delete_project(pr)
    project = sa.create_project(PROJECT_NAME, "gg", "Vector")
    sa.upload_images_from_folder_to_project(project,
                                            "./tests/sample_project_vector/",
                                            annotation_status="QualityCheck")
    sa.create_annotation_classes_from_classes_json(
        project,
        "./tests/sample_project_vector/classes/classes.json",
    )
    sa.upload_annotations_from_folder_to_project(
        project,
        "./tests/sample_project_vector/",
    )
    export = sa.prepare_export(project)
    sa.download_export(project, export, tmpdir)
    js = list(tmpdir.glob("*.json"))

    assert len(js) == 4
Exemple #16
0
def test_fuse_image_create_vector(tmpdir):
    tmpdir = Path(tmpdir)

    projects = sa.search_projects(PROJECT_NAME_VECTOR, return_metadata=True)
    for project in projects:
        sa.delete_project(project)

    project = sa.create_project(PROJECT_NAME_VECTOR, "test", "Vector")

    sa.upload_image_to_project(
        project,
        "./tests/sample_project_vector/example_image_1.jpg",
        annotation_status="QualityCheck")

    sa.create_annotation_classes_from_classes_json(
        project, "./tests/sample_project_vector/classes/classes.json")

    sa.add_annotation_bbox_to_image(project, "example_image_1.jpg",
                                    [20, 20, 40, 40], "Human")
    sa.add_annotation_polygon_to_image(project, "example_image_1.jpg",
                                       [60, 60, 100, 100, 80, 100],
                                       "Personal vehicle")
    sa.add_annotation_polyline_to_image(project, "example_image_1.jpg",
                                        [200, 200, 300, 200, 350, 300],
                                        "Personal vehicle")
    sa.add_annotation_point_to_image(project, "example_image_1.jpg",
                                     [400, 400], "Personal vehicle")
    sa.add_annotation_ellipse_to_image(project, "example_image_1.jpg",
                                       [600, 600, 50, 100, 20],
                                       "Personal vehicle")
    sa.add_annotation_template_to_image(
        project, "example_image_1.jpg",
        [600, 300, 600, 350, 550, 250, 650, 250, 550, 400, 650, 400],
        [1, 2, 3, 1, 4, 1, 5, 2, 6, 2], "Human")
    sa.add_annotation_cuboid_to_image(project, "example_image_1.jpg",
                                      [60, 300, 200, 350, 120, 325, 250, 500],
                                      "Human")

    export = sa.prepare_export(project, include_fuse=True)
    (tmpdir / "export").mkdir()
    sa.download_export(project, export, (tmpdir / "export"))

    # sa.create_fuse_image(
    #     "./tests/sample_project_vector/example_image_1.jpg",
    #     "./tests/sample_project_vector/classes/classes.json", "Vector"
    # )

    paths = sa.download_image(project,
                              "example_image_1.jpg",
                              tmpdir,
                              include_annotations=True,
                              include_fuse=True,
                              include_overlay=True)
    im1 = Image.open(tmpdir / "export" / "example_image_1.jpg___fuse.png")
    im1_array = np.array(im1)

    im2 = Image.open(paths[2][0])
    im2_array = np.array(im2)

    assert im1_array.shape == im2_array.shape
    assert im1_array.dtype == im2_array.dtype
Exemple #17
0
def test_add_bbox(tmpdir):
    tmpdir = Path(tmpdir)

    projects_found = sa.search_projects(PROJECT_NAME, return_metadata=True)
    for pr in projects_found:
        if pr["name"] == PROJECT_NAME:
            sa.delete_project(pr)

    project = sa.create_project(PROJECT_NAME, PROJECT_DESCRIPTION, "Vector")
    sa.upload_images_from_folder_to_project(PROJECT_NAME,
                                            PATH_TO_SAMPLE_PROJECT,
                                            annotation_status="InProgress")
    sa.create_annotation_classes_from_classes_json(
        project, PATH_TO_SAMPLE_PROJECT / "classes" / "classes.json")
    sa.create_annotation_class(
        project, "test_add", "#FF0000",
        [{
            "name": "height",
            "attributes": [{
                "name": "tall"
            }, {
                "name": "short"
            }]
        }])
    sa.upload_annotations_from_folder_to_project(project,
                                                 PATH_TO_SAMPLE_PROJECT)

    images = sa.search_images(project, "example_image_1")

    image_name = images[0]
    annotations = sa.get_image_annotations(project,
                                           image_name)["annotation_json"]

    sa.add_annotation_bbox_to_image(project, image_name, [10, 10, 500, 100],
                                    "test_add")
    sa.add_annotation_polyline_to_image(project, image_name,
                                        [110, 110, 510, 510, 600, 510],
                                        "test_add")
    sa.add_annotation_polygon_to_image(project, image_name,
                                       [100, 100, 500, 500, 200, 300],
                                       "test_add", [{
                                           "name": "tall",
                                           "groupName": "height"
                                       }])
    sa.add_annotation_point_to_image(project, image_name, [250, 250],
                                     "test_add")
    sa.add_annotation_ellipse_to_image(project, image_name,
                                       [405, 405, 20, 70, 15], "test_add")
    sa.add_annotation_template_to_image(project, image_name,
                                        [600, 30, 630, 30, 615, 60],
                                        [1, 3, 2, 3], "test_add")
    sa.add_annotation_cuboid_to_image(project, image_name,
                                      [800, 500, 900, 600, 850, 450, 950, 700],
                                      "test_add")
    sa.add_annotation_comment_to_image(project, image_name, "hey", [100, 100],
                                       "*****@*****.**", True)
    annotations_new = sa.get_image_annotations(project,
                                               image_name)["annotation_json"]
    json.dump(annotations_new, open(tmpdir / "new_anns.json", "w"))

    assert len(annotations_new["instances"]) + len(
        annotations_new["comments"]) == len(annotations["instances"]) + len(
            annotations["comments"]) + 8

    export = sa.prepare_export(project, include_fuse=True)
    sa.download_export(project, export, tmpdir)

    df = sa.aggregate_annotations_as_df(tmpdir)
    print(df)
    print(image_name)

    num = len(
        df[df["imageName"] == image_name]["instanceId"].dropna().unique())

    assert num == len(
        annotations["instances"]
    ) - 3 + 7  # -6 for 3 comments and 3 invalid annotations, className or attributes
Exemple #18
0
def test_basic_project(project_type, name, description, from_folder, tmpdir):
    tmpdir = Path(tmpdir)

    projects_found = sa.search_projects(name, return_metadata=True)
    for pr in projects_found:
        sa.delete_project(pr)

    projects_found = sa.search_projects(name, return_metadata=True)
    assert len(projects_found) == 0

    project = sa.create_project(name, description, project_type)
    assert project["name"] == name
    assert project["description"] == description
    assert project["type"] == project_type

    projects_found = sa.search_projects(name)
    assert len(projects_found) == 1
    assert projects_found[0] == name

    sa.upload_images_from_folder_to_project(project,
                                            from_folder,
                                            annotation_status="InProgress")

    count_in_folder = len(list(from_folder.glob("*.jpg"))) + len(
        list(from_folder.glob("*.png")))
    count_in_folder -= len(list(from_folder.glob("*___fuse.png")))
    if project_type == "Pixel":
        count_in_folder -= len(list(from_folder.glob("*___save.png")))
    images = sa.search_images(project)
    assert count_in_folder == len(images)

    sa.create_annotation_classes_from_classes_json(
        project, from_folder / "classes" / "classes.json")
    classes_in_file = json.load(open(from_folder / "classes" / "classes.json"))
    classes_in_project = sa.search_annotation_classes(project)
    json.dump(classes_in_project, open(Path(tmpdir) / "tmp_c.json", 'w'))
    assert len(classes_in_file) == len(classes_in_project)
    for cl_f in classes_in_file:
        found = False
        for cl_c in classes_in_project:
            if cl_f["name"] == cl_c["name"]:
                found = True
                break
        assert found

    sa.upload_annotations_from_folder_to_project(project, from_folder)

    export = sa.prepare_export(project)

    sa.download_export(project, export, tmpdir)
    for image in from_folder.glob("*.[jpg|png]"):
        found = False
        for image_in_project in tmpdir.glob("*.jpg"):
            if image.name == image_in_project.name:
                found = True
                break
        assert found, image

    for json_in_folder in from_folder.glob("*.json"):
        found = False
        for json_in_project in tmpdir.glob("*.json"):
            if json_in_folder.name == json_in_project.name:
                found = True
                break
        assert found, json_in_folder
    if project_type == "Pixel":
        for mask_in_folder in from_folder.glob("*___save.png"):
            found = False
            for mask_in_project in tmpdir.glob("*___save.png"):
                if mask_in_folder.name == mask_in_project.name:
                    found = True
                    break
            assert found, mask_in_folder