Skip to content

Commit 7300c77

Browse files
authored
Merge pull request #30 from superannotateai/develop
release
2 parents 7c3f27b + 41b3576 commit 7300c77

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+3177
-612
lines changed

.vscode/settings.json

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
{
2+
"editor.formatOnSave": true,
23
"python.formatting.provider": "yapf",
3-
"python.linting.pylintPath": "venv_sa_conv/bin/pylint",
4-
"python.linting.pylintEnabled": true,
5-
"python.testing.pytestArgs": [
6-
"tests"
7-
],
8-
"python.testing.unittestEnabled": false,
9-
"python.testing.nosetestsEnabled": false,
10-
"python.testing.pytestEnabled": true,
11-
"python.pythonPath": "venv_sa_conv/bin/python"
4+
// "python.linting.pylintPath": "venv_sa_conv/bin/pylint",
5+
// "python.linting.pylintEnabled": true,
6+
// "python.testing.pytestArgs": [
7+
// "tests"
8+
// ],
9+
// "python.testing.unittestEnabled": false,
10+
// "python.testing.nosetestsEnabled": false,
11+
// "python.testing.pytestEnabled": true,
12+
// "python.pythonPath": "venv_sa_conv/bin/python"
1213
}

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ pandas>=1.1.2
1515
plotly>=4.1.0
1616
ffmpeg-python>=0.2.0
1717
google-cloud-storage>=1.33.0
18-
azure-storage-blob>=12.6.0
18+
azure-storage-blob>=12.6.0
19+
mixpanel>=4.8.3

superannotate/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ def consensus(*args, **kwargs):
5050
download_image_preannotations, get_image_annotations, get_image_bytes,
5151
get_image_metadata, get_image_preannotations, search_images,
5252
search_images_all_folders, set_image_annotation_status,
53-
set_images_annotation_statuses, upload_image_annotations, get_project_root_folder_id
53+
set_images_annotation_statuses, upload_image_annotations,
54+
get_project_root_folder_id
5455
)
5556
from .db.project_api import (
5657
create_folder, delete_folders, get_folder_metadata,

superannotate/analytics/class_analytics.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
from plotly.subplots import make_subplots
99

1010
from .common import aggregate_annotations_as_df
11+
from ..mixp.decorators import Trackable
1112

1213
logger = logging.getLogger("superannotate-python-sdk")
1314

1415

16+
@Trackable
1517
def class_distribution(export_root, project_names, visualize=False):
1618
"""Aggregate distribution of classes across multiple projects.
1719
@@ -63,6 +65,7 @@ def class_distribution(export_root, project_names, visualize=False):
6365
return df
6466

6567

68+
@Trackable
6669
def attribute_distribution(export_root, project_names, visualize=False):
6770
"""Aggregate distribution of attributes across multiple projects.
6871

superannotate/analytics/common.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
import pandas as pd
77

88
from ..exceptions import SABaseException
9+
from ..mixp.decorators import Trackable
910

1011
logger = logging.getLogger("superannotate-python-sdk")
1112

1213

14+
@Trackable
1315
def df_to_annotations(df, output_dir):
1416
"""Converts and saves pandas DataFrame annotation info (see aggregate_annotations_as_df)
1517
in output_dir.
@@ -148,6 +150,7 @@ def df_to_annotations(df, output_dir):
148150
)
149151

150152

153+
@Trackable
151154
def aggregate_annotations_as_df(
152155
project_root,
153156
include_classes_wo_annotations=False,

superannotate/api.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import json
33
import logging
4+
import sys
45
from pathlib import Path
56

67
import requests
@@ -9,6 +10,7 @@
910

1011
from .exceptions import SABaseException
1112
from .version import __version__
13+
from .mixp.app import mp, get_default
1214

1315
logger = logging.getLogger("superannotate-python-sdk")
1416

@@ -24,10 +26,13 @@ def __init__(self):
2426
self._default_headers = None
2527
self._main_endpoint = None
2628
self.team_id = None
29+
self.user_id = None
30+
self.team_name = None
2731
if API.__instance is not None:
2832
raise SABaseException(0, "API class is a singleton!")
2933
API.__instance = self
3034
self._authenticated = False
35+
self.init()
3136

3237
def init(self, config_location=None):
3338
if config_location is None:
@@ -78,15 +83,15 @@ def init(self, config_location=None):
7883
self._verify = self._api_config["ssl_verify"]
7984
self._session = None
8085
self._authenticated = True
86+
8187
response = self.send_request(
8288
req_type='GET',
83-
path='/projects',
84-
params={
85-
'team_id': str(self.team_id),
86-
'offset': 0,
87-
'limit': 1
88-
}
89+
path=f'/team/{self.team_id}',
8990
)
91+
92+
self.user_id = response.json().get('creator_id', None)
93+
self.team_name = response.json().get('name', None)
94+
9095
if not self._verify:
9196
urllib3.disable_warnings(
9297
urllib3.exceptions.InsecureRequestWarning
@@ -102,6 +107,11 @@ def init(self, config_location=None):
102107
raise SABaseException(
103108
0, "Couldn't reach superannotate " + response.text
104109
)
110+
if "pytest" not in sys.modules:
111+
mp.track(
112+
self.user_id, "SDK init",
113+
get_default(self.team_name, self.user_id)
114+
)
105115
except SABaseException:
106116
self._authenticated = False
107117
self._session = None

superannotate/common.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@
5252
}
5353

5454
_MODEL_TRAINING_TASKS = {
55-
"Instance Segmentation for Pixel Projects" : "instance_segmentation_pixel",
56-
"Instance Segmentation for Vector Projects" : "instance_segmentation_vector",
57-
"Keypoint Detection for Vector Projects" : "keypoint_detection_vector",
58-
"Object Detection for Vector Projects" : "object_detection_vector",
59-
"Semantic Segmentation for Pixel Projects" : "semantic_segmentation_pixel"
55+
"Instance Segmentation for Pixel Projects": "instance_segmentation_pixel",
56+
"Instance Segmentation for Vector Projects": "instance_segmentation_vector",
57+
"Keypoint Detection for Vector Projects": "keypoint_detection_vector",
58+
"Object Detection for Vector Projects": "object_detection_vector",
59+
"Semantic Segmentation for Pixel Projects": "semantic_segmentation_pixel"
6060
}
6161

6262

superannotate/consensus_benchmark/benchmark.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
from .helpers import image_consensus, consensus_plot
1010
from ..db.exports import prepare_export, download_export
1111
from ..analytics.common import aggregate_annotations_as_df
12+
from ..mixp.decorators import Trackable
1213

1314
logger = logging.getLogger("superannotate-python-sdk")
1415

1516

17+
@Trackable
1618
def benchmark(
1719
project,
1820
gt_folder,

superannotate/consensus_benchmark/consensus.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
from .helpers import image_consensus, consensus_plot
1010
from ..db.exports import prepare_export, download_export
1111
from ..analytics.common import aggregate_annotations_as_df
12+
from ..mixp.decorators import Trackable
1213

1314
logger = logging.getLogger("superannotate-python-sdk")
1415

1516

17+
@Trackable
1618
def consensus(
1719
project,
1820
folder_names,

superannotate/consensus_benchmark/helpers.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,32 +80,43 @@ def image_consensus(df, image_name, annot_type):
8080
"Invalid %s instance occured, skipping to the next one.",
8181
annot_type
8282
)
83+
visited_instances = {}
84+
for proj, instances in projects_shaply_objs.items():
85+
visited_instances[proj] = [False] * len(instances)
8386

8487
# match instances
8588
for curr_proj, curr_proj_instances in projects_shaply_objs.items():
86-
for curr_inst_data in curr_proj_instances:
89+
for curr_id, curr_inst_data in enumerate(curr_proj_instances):
8790
curr_inst, curr_class, _, _ = curr_inst_data
91+
if visited_instances[curr_proj][curr_id] == True:
92+
continue
8893
max_instances = []
8994
for other_proj, other_proj_instances in projects_shaply_objs.items(
9095
):
9196
if curr_proj == other_proj:
9297
max_instances.append((curr_proj, *curr_inst_data))
93-
projects_shaply_objs[curr_proj].remove(curr_inst_data)
98+
visited_instances[curr_proj][curr_id] = True
9499
else:
95100
if annot_type in ['polygon', 'bbox']:
96101
max_score = 0
97102
else:
98103
max_score = float('-inf')
99104
max_inst_data = None
100-
for other_inst_data in other_proj_instances:
105+
max_inst_id = -1
106+
for other_id, other_inst_data in enumerate(
107+
other_proj_instances
108+
):
101109
other_inst, other_class, _, _ = other_inst_data
110+
if visited_instances[other_proj][other_id] == True:
111+
continue
102112
score = instance_consensus(curr_inst, other_inst)
103113
if score > max_score and other_class == curr_class:
104114
max_score = score
105115
max_inst_data = other_inst_data
116+
max_inst_id = other_id
106117
if max_inst_data is not None:
107118
max_instances.append((other_proj, *max_inst_data))
108-
projects_shaply_objs[other_proj].remove(max_inst_data)
119+
visited_instances[other_proj][max_inst_id] = True
109120
if len(max_instances) == 1:
110121
image_data["creatorEmail"].append(max_instances[0][3])
111122
image_data["attributes"].append(max_instances[0][4])

0 commit comments

Comments
 (0)