Skip to content

Commit 3a3e8c9

Browse files
authored
Merge pull request #26 from superannotateai/mixpanel
Mixpanel - copy - move
2 parents 0d8bdde + 4649c8d commit 3a3e8c9

30 files changed

+2086
-83
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/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: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from .exceptions import SABaseException
1111
from .version import __version__
12+
from .mixp.app import mp, get_default
1213

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

@@ -24,10 +25,13 @@ def __init__(self):
2425
self._default_headers = None
2526
self._main_endpoint = None
2627
self.team_id = None
28+
self.user_id = None
29+
self.team_name = None
2730
if API.__instance is not None:
2831
raise SABaseException(0, "API class is a singleton!")
2932
API.__instance = self
3033
self._authenticated = False
34+
self.init()
3135

3236
def init(self, config_location=None):
3337
if config_location is None:
@@ -78,15 +82,15 @@ def init(self, config_location=None):
7882
self._verify = self._api_config["ssl_verify"]
7983
self._session = None
8084
self._authenticated = True
85+
8186
response = self.send_request(
8287
req_type='GET',
83-
path='/projects',
84-
params={
85-
'team_id': str(self.team_id),
86-
'offset': 0,
87-
'limit': 1
88-
}
88+
path=f'/team/{self.team_id}',
8989
)
90+
91+
self.user_id = response.json()['creator_id']
92+
self.team_name = response.json()['name']
93+
9094
if not self._verify:
9195
urllib3.disable_warnings(
9296
urllib3.exceptions.InsecureRequestWarning
@@ -102,6 +106,10 @@ def init(self, config_location=None):
102106
raise SABaseException(
103107
0, "Couldn't reach superannotate " + response.text
104108
)
109+
mp.track(
110+
self.user_id, "SDK init",
111+
get_default(self.team_name, self.user_id)
112+
)
105113
except SABaseException:
106114
self._authenticated = False
107115
self._session = None

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])

superannotate/dataframe_filtering.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import pandas as pd
2+
from .mixp.decorators import Trackable
23

34

5+
@Trackable
46
def filter_images_by_comments(
57
annotations_df,
68
include_unresolved_comments=True,
@@ -40,6 +42,7 @@ def filter_images_by_comments(
4042
return list(images)
4143

4244

45+
@Trackable
4346
def filter_images_by_tags(annotations_df, include=None, exclude=None):
4447
"""Filter images on tags
4548
@@ -74,6 +77,7 @@ def filter_images_by_tags(annotations_df, include=None, exclude=None):
7477
return list(images)
7578

7679

80+
@Trackable
7781
def filter_annotation_instances(annotations_df, include=None, exclude=None):
7882
"""Filter annotation instances from project annotations pandas DataFrame.
7983

superannotate/db/annotation_classes.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
SANonExistingAnnotationClassNameException
1212
)
1313
from .project_api import get_project_metadata_bare
14+
from ..mixp.decorators import Trackable
1415

1516
logger = logging.getLogger("superannotate-python-sdk")
1617

1718
_api = API.get_instance()
1819

1920

21+
@Trackable
2022
def create_annotation_class(project, name, color, attribute_groups=None):
2123
"""Create annotation class in project
2224
@@ -79,6 +81,7 @@ def create_annotation_class(project, name, color, attribute_groups=None):
7981
return new_class
8082

8183

84+
@Trackable
8285
def delete_annotation_class(project, annotation_class):
8386
"""Deletes annotation class from project
8487
@@ -113,6 +116,7 @@ def delete_annotation_class(project, annotation_class):
113116
)
114117

115118

119+
@Trackable
116120
def create_annotation_classes_from_classes_json(
117121
project, classes_json, from_s3_bucket=None
118122
):
@@ -200,6 +204,7 @@ def del_unn(d):
200204
return res
201205

202206

207+
@Trackable
203208
def search_annotation_classes(project, name_prefix=None):
204209
"""Searches annotation classes by name_prefix (case-insensitive)
205210
@@ -239,6 +244,7 @@ def search_annotation_classes(project, name_prefix=None):
239244
return result_list
240245

241246

247+
@Trackable
242248
def get_annotation_class_metadata(project, annotation_class_name):
243249
"""Returns annotation class metadata
244250
@@ -272,6 +278,7 @@ def get_annotation_class_metadata(project, annotation_class_name):
272278
)
273279

274280

281+
@Trackable
275282
def download_annotation_classes_json(project, folder):
276283
"""Downloads project classes.json to folder
277284

0 commit comments

Comments
 (0)