From 0943c9978321ccd45415343cde3e073fb539de2c Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 13:28:51 -0400 Subject: [PATCH 01/18] added class variables --- roboflow/core/project.py | 2 +- roboflow/core/version.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index ad213876..114662bc 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -54,7 +54,7 @@ def version(self, version_number): current_version_num = os.path.basename(version_object['id']) if current_version_num == version_number: - vers = Version(self.category, self.api_key, self.name, current_version_num, local=False) + vers = Version(version_object, self.category, self.api_key, self.name, current_version_num, local=False) return vers raise RuntimeError("Version number {} is not found.".format(version_number)) diff --git a/roboflow/core/version.py b/roboflow/core/version.py index 2db639f8..ee3ca436 100644 --- a/roboflow/core/version.py +++ b/roboflow/core/version.py @@ -3,9 +3,8 @@ import os import json - class Version(): - def __init__(self, type, api_key, dataset_slug, version, local): + def __init__(self, version_dict, type, api_key, dataset_slug, version, local): self.api_key = api_key self.name = dataset_slug self.version = version @@ -20,6 +19,16 @@ def __init__(self, type, api_key, dataset_slug, version, local): else: self.model = None + self.set_class_variables() + + def set_class_variables(self, version_dict): + self.augmentation=version_dict['augmentation'] + self.created=version_dict['created'] + self.id=version_dict['id'] + self.images=version_dict['images'] + self.preprocessing=version_dict['preprocessing'] + self.splits=version_dict['splits'] + def __str__(self): json_value = {'api_key': self.api_key, 'name': self.name, From d0bc13ceb87c3001e08e75d4ea8b1097c94cdd65 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 14:09:04 -0400 Subject: [PATCH 02/18] workspace fields --- roboflow/core/version.py | 2 +- roboflow/core/workspace.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/roboflow/core/version.py b/roboflow/core/version.py index ee3ca436..b0ad78a3 100644 --- a/roboflow/core/version.py +++ b/roboflow/core/version.py @@ -19,7 +19,7 @@ def __init__(self, version_dict, type, api_key, dataset_slug, version, local): else: self.model = None - self.set_class_variables() + self.set_class_variables(version_dict) def set_class_variables(self, version_dict): self.augmentation=version_dict['augmentation'] diff --git a/roboflow/core/workspace.py b/roboflow/core/workspace.py index 799fc1d6..5c5f295c 100644 --- a/roboflow/core/workspace.py +++ b/roboflow/core/workspace.py @@ -1,21 +1,28 @@ import requests from roboflow.core.project import Project from roboflow.config import * +import pprint class Workspace(): def __init__(self, info, api_key, default_workspace): - self.api_key = api_key self.name = default_workspace workspace_info = info['workspace'] - self.members = workspace_info['members'] self.url = workspace_info['url'] self.project_list = [] for value in info['workspace']['projects']: self.project_list.append(value) + self.set_class_variables(info) + + def set_class_variables(self, info): + w = info['workspace'] + self.members=w['members'] + self.projects=w['projects'] + self.url=w['url'] + def list_projects(self): print(self.projects) From bab579efd00818a793b997af8267dc0b746139c6 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 14:23:08 -0400 Subject: [PATCH 03/18] changed project() method to return right version of project class --- roboflow/__init__.py | 7 +++++-- roboflow/core/project.py | 1 + roboflow/core/workspace.py | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/roboflow/__init__.py b/roboflow/__init__.py index 0886a45a..29d02bca 100644 --- a/roboflow/__init__.py +++ b/roboflow/__init__.py @@ -68,9 +68,12 @@ def project(self, project_name, the_workspace=None): dataset_info = dataset_info.json()['project'] - return Project(self.api_key, dataset_info['id'], dataset_info['type'], dataset_info['versions']) + split = dataset_info['id'].rsplit("/") + workspace, project_name = split[0], split[1] + + return Project(self.api_key, project_name, dataset_info['type'], workspace) def __str__(self): json_value = {'api_key': self.api_key, 'workspace': self.workspace} - return json.dumps(json_value, indent=2) + return json.dumps(json_value, indent=2) \ No newline at end of file diff --git a/roboflow/core/project.py b/roboflow/core/project.py index 114662bc..dfb15fb5 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -13,6 +13,7 @@ #version class that should return class Project(): def __init__(self, api_key, dataset_slug, type, workspace): + self.api_key = api_key self.name = dataset_slug self.category = type diff --git a/roboflow/core/workspace.py b/roboflow/core/workspace.py index 5c5f295c..35c25a5f 100644 --- a/roboflow/core/workspace.py +++ b/roboflow/core/workspace.py @@ -49,5 +49,7 @@ def project(self, project_name): raise RuntimeError(dataset_info.text) dataset_info = dataset_info.json()['project'] + split = dataset_info['id'].rsplit("/") + workspace, project_name = split[0], split[1] - return Project(self.api_key, dataset_info['id'], dataset_info['type'], dataset_info['versions']) + return Project(self.api_key, project_name, dataset_info['type'], workspace) From 510200af4db99b46c60e5fe92949ec4a0f9cd59e Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 14:30:31 -0400 Subject: [PATCH 04/18] removed imports --- roboflow/core/workspace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/roboflow/core/workspace.py b/roboflow/core/workspace.py index 35c25a5f..2a4e7825 100644 --- a/roboflow/core/workspace.py +++ b/roboflow/core/workspace.py @@ -1,7 +1,6 @@ import requests from roboflow.core.project import Project from roboflow.config import * -import pprint class Workspace(): def __init__(self, info, api_key, default_workspace): From d58e378e59eff86f865201223f01a6a3e3fa1dbc Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 15:47:54 -0400 Subject: [PATCH 05/18] removed conflicting projects --- roboflow/core/workspace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/roboflow/core/workspace.py b/roboflow/core/workspace.py index 2a4e7825..cf656abf 100644 --- a/roboflow/core/workspace.py +++ b/roboflow/core/workspace.py @@ -19,7 +19,6 @@ def __init__(self, info, api_key, default_workspace): def set_class_variables(self, info): w = info['workspace'] self.members=w['members'] - self.projects=w['projects'] self.url=w['url'] def list_projects(self): From e114f01a82f701167c80ed58ee06a16a00a74d94 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 16:01:58 -0400 Subject: [PATCH 06/18] added versioning changes to fix projects bug --- roboflow/core/project.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index dfb15fb5..060158c7 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -21,11 +21,11 @@ def __init__(self, api_key, dataset_slug, type, workspace): self.all_versions = [] def get_version_information(self): + print(self.workspace) + # slug_splitted = self.name.rsplit("/") + # p, w = slug_splitted[0], slug_splitted[1] - slug_splitted = self.name.rsplit("/") - p, w = slug_splitted[0], slug_splitted[1] - - dataset_info = requests.get(API_URL + "/" + p + "/" + w + "?api_key=" + self.api_key) + dataset_info = requests.get(API_URL + "/" + self.workspace + "/" + self.name + "?api_key=" + self.api_key) # Throw error if dataset isn't valid/user doesn't have permissions to access the dataset if dataset_info.status_code != 200: @@ -42,7 +42,7 @@ def versions(self): version_info = self.get_version_information() version_array = [] for a_version in version_info: - version_object = Version((self.category if 'model' in a_version else None), self.api_key, self.name, a_version['id'], local=False) + version_object = Version(a_version, (self.category if 'model' in a_version else None), self.api_key, self.name, a_version['id'], local=False) version_array.append(version_object) return version_array From d39c3ffcf32854cc747c615fea07e24d3666888d Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 16:11:54 -0400 Subject: [PATCH 07/18] enhanced __str__() methods --- roboflow/core/project.py | 12 +++++++----- roboflow/core/version.py | 34 ++++++++++++++++++---------------- roboflow/core/workspace.py | 11 ++++++++++- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index 060158c7..11c89fcd 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -16,7 +16,7 @@ def __init__(self, api_key, dataset_slug, type, workspace): self.api_key = api_key self.name = dataset_slug - self.category = type + self.type = type self.workspace = workspace self.all_versions = [] @@ -42,7 +42,7 @@ def versions(self): version_info = self.get_version_information() version_array = [] for a_version in version_info: - version_object = Version(a_version, (self.category if 'model' in a_version else None), self.api_key, self.name, a_version['id'], local=False) + version_object = Version(a_version, (self.type if 'model' in a_version else None), self.api_key, self.name, a_version['id'], local=False) version_array.append(version_object) return version_array @@ -55,7 +55,7 @@ def version(self, version_number): current_version_num = os.path.basename(version_object['id']) if current_version_num == version_number: - vers = Version(version_object, self.category, self.api_key, self.name, current_version_num, local=False) + vers = Version(version_object, self.type, self.api_key, self.name, current_version_num, local=False) return vers raise RuntimeError("Version number {} is not found.".format(version_number)) @@ -168,8 +168,10 @@ def __str__(self): # String representation of project json_str = { "dataset_slug": self.name, - "task_type": self.category, - "workspace": self.workspace + "type": self.type, + "workspace": self.workspace, + + } return json.dumps(json_str, indent=2) diff --git a/roboflow/core/version.py b/roboflow/core/version.py index b0ad78a3..91f23ef2 100644 --- a/roboflow/core/version.py +++ b/roboflow/core/version.py @@ -3,18 +3,19 @@ import os import json + class Version(): def __init__(self, version_dict, type, api_key, dataset_slug, version, local): self.api_key = api_key self.name = dataset_slug self.version = version - self.category = type + self.type = type version_without_workspace = os.path.basename(version) - if self.category == "object-detection": + if self.type == "object-detection": self.model = ObjectDetectionModel(self.api_key, self.name, version_without_workspace, local=local) - elif self.category == "classification": + elif self.type == "classification": self.model = ClassificationModel(self.api_key, self.name, version_without_workspace, local=local) else: self.model = None @@ -22,19 +23,20 @@ def __init__(self, version_dict, type, api_key, dataset_slug, version, local): self.set_class_variables(version_dict) def set_class_variables(self, version_dict): - self.augmentation=version_dict['augmentation'] - self.created=version_dict['created'] - self.id=version_dict['id'] - self.images=version_dict['images'] - self.preprocessing=version_dict['preprocessing'] - self.splits=version_dict['splits'] + self.augmentation = version_dict['augmentation'] + self.created = version_dict['created'] + self.id = version_dict['id'] + self.images = version_dict['images'] + self.preprocessing = version_dict['preprocessing'] + self.splits = version_dict['splits'] def __str__(self): - json_value = {'api_key': self.api_key, - 'name': self.name, - 'model_type': str(self.model), - 'version': self.version} + json_value = { + 'name': self.name, + 'type': self.type, + 'version': self.version, + 'augmentation': self.augmentation, + 'created': self.created, + 'preprocessing': self.preprocessing, + 'splits': self.splits} return json.dumps(json_value, indent=2) - - - diff --git a/roboflow/core/workspace.py b/roboflow/core/workspace.py index cf656abf..dbf166fa 100644 --- a/roboflow/core/workspace.py +++ b/roboflow/core/workspace.py @@ -1,4 +1,5 @@ import requests +import json from roboflow.core.project import Project from roboflow.config import * @@ -8,7 +9,6 @@ def __init__(self, info, api_key, default_workspace): self.name = default_workspace workspace_info = info['workspace'] - self.url = workspace_info['url'] self.project_list = [] for value in info['workspace']['projects']: @@ -51,3 +51,12 @@ def project(self, project_name): workspace, project_name = split[0], split[1] return Project(self.api_key, project_name, dataset_info['type'], workspace) + + def __str__(self): + json_value = {'name': self.name, + 'url': self.url, + 'members': self.members, + } + + return json.dumps(json_value, indent=2) + From 17b2fae44a1d8d33f9e772d6f3e018760b54c7d6 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 17:14:47 -0400 Subject: [PATCH 08/18] changes in structure --- roboflow/__init__.py | 7 ++----- roboflow/core/project.py | 35 ++++++++++++++++++++--------------- roboflow/core/version.py | 16 ++++++---------- roboflow/core/workspace.py | 30 ++++++++++-------------------- 4 files changed, 38 insertions(+), 50 deletions(-) diff --git a/roboflow/__init__.py b/roboflow/__init__.py index 29d02bca..e03a5c11 100644 --- a/roboflow/__init__.py +++ b/roboflow/__init__.py @@ -68,12 +68,9 @@ def project(self, project_name, the_workspace=None): dataset_info = dataset_info.json()['project'] - split = dataset_info['id'].rsplit("/") - workspace, project_name = split[0], split[1] - - return Project(self.api_key, project_name, dataset_info['type'], workspace) + return Project(self.api_key, dataset_info) def __str__(self): json_value = {'api_key': self.api_key, 'workspace': self.workspace} - return json.dumps(json_value, indent=2) \ No newline at end of file + return json.dumps(json_value, indent=2) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index 11c89fcd..c76dc0f5 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -3,6 +3,7 @@ import json import os import urllib +import datetime import warnings import cv2 import requests @@ -12,20 +13,27 @@ #version class that should return class Project(): - def __init__(self, api_key, dataset_slug, type, workspace): - + def __init__(self, api_key, a_project): self.api_key = api_key - self.name = dataset_slug - self.type = type - self.workspace = workspace - self.all_versions = [] + self.annotation = a_project['annotation'] + self.classes = a_project['classes'] + self.colors = a_project['colors'] + self.created = datetime.datetime.fromtimestamp(a_project['created']) + self.id = a_project['id'] + self.images = a_project['images'] + self.name = a_project['name'] + self.public = a_project['public'] + self.splits = a_project['splits'] + self.type = a_project['type'] + self.unannotated = a_project['unannotated'] + self.updated = datetime.datetime.fromtimestamp(a_project['updated']) + + temp = self.id.rsplit("/") + self.__workspace = temp[0] + self.__project_name = temp[1] def get_version_information(self): - print(self.workspace) - # slug_splitted = self.name.rsplit("/") - # p, w = slug_splitted[0], slug_splitted[1] - - dataset_info = requests.get(API_URL + "/" + self.workspace + "/" + self.name + "?api_key=" + self.api_key) + dataset_info = requests.get(API_URL + "/" + self.__workspace + "/" + self.__project_name + "?api_key=" + self.api_key) # Throw error if dataset isn't valid/user doesn't have permissions to access the dataset if dataset_info.status_code != 200: @@ -44,7 +52,6 @@ def versions(self): for a_version in version_info: version_object = Version(a_version, (self.type if 'model' in a_version else None), self.api_key, self.name, a_version['id'], local=False) version_array.append(version_object) - return version_array def version(self, version_number): @@ -169,9 +176,7 @@ def __str__(self): json_str = { "dataset_slug": self.name, "type": self.type, - "workspace": self.workspace, - - + "workspace": self.__workspace, } return json.dumps(json_str, indent=2) diff --git a/roboflow/core/version.py b/roboflow/core/version.py index 91f23ef2..75717273 100644 --- a/roboflow/core/version.py +++ b/roboflow/core/version.py @@ -10,6 +10,12 @@ def __init__(self, version_dict, type, api_key, dataset_slug, version, local): self.name = dataset_slug self.version = version self.type = type + self.augmentation = version_dict['augmentation'] + self.created = version_dict['created'] + self.id = version_dict['id'] + self.images = version_dict['images'] + self.preprocessing = version_dict['preprocessing'] + self.splits = version_dict['splits'] version_without_workspace = os.path.basename(version) @@ -20,16 +26,6 @@ def __init__(self, version_dict, type, api_key, dataset_slug, version, local): else: self.model = None - self.set_class_variables(version_dict) - - def set_class_variables(self, version_dict): - self.augmentation = version_dict['augmentation'] - self.created = version_dict['created'] - self.id = version_dict['id'] - self.images = version_dict['images'] - self.preprocessing = version_dict['preprocessing'] - self.splits = version_dict['splits'] - def __str__(self): json_value = { 'name': self.name, diff --git a/roboflow/core/workspace.py b/roboflow/core/workspace.py index dbf166fa..813a2990 100644 --- a/roboflow/core/workspace.py +++ b/roboflow/core/workspace.py @@ -5,31 +5,22 @@ class Workspace(): def __init__(self, info, api_key, default_workspace): - self.api_key = api_key - self.name = default_workspace - workspace_info = info['workspace'] - self.project_list = [] - - for value in info['workspace']['projects']: - self.project_list.append(value) + self.name = workspace_info['name'] + self.project_list = workspace_info['projects'] + self.members = workspace_info['members'] + self.url = workspace_info['url'] - self.set_class_variables(info) + self.__api_key = api_key - def set_class_variables(self, info): - w = info['workspace'] - self.members=w['members'] - self.url=w['url'] def list_projects(self): - print(self.projects) + print(self.project_list) def projects(self): projects_array = [] for a_project in self.project_list: - split = a_project['id'].rsplit("/") - workspace, project_name = split[0], split[1] - proj = Project(self.api_key, project_name, a_project['type'], workspace) + proj = Project(self.__api_key, a_project) projects_array.append(proj) return projects_array @@ -40,22 +31,21 @@ def project(self, project_name): if "/" in project_name: raise RuntimeError("Do not re-specify the workspace {} in your project request".format(project_name.rsplit()[0])) - dataset_info = requests.get(API_URL + "/" + self.name + "/" + project_name + "?api_key=" + self.api_key) + dataset_info = requests.get(API_URL + "/" + self.url + "/" + project_name + "?api_key=" + self.__api_key) # Throw error if dataset isn't valid/user doesn't have permissions to access the dataset if dataset_info.status_code != 200: raise RuntimeError(dataset_info.text) dataset_info = dataset_info.json()['project'] - split = dataset_info['id'].rsplit("/") - workspace, project_name = split[0], split[1] - return Project(self.api_key, project_name, dataset_info['type'], workspace) + return Project(self.__api_key, dataset_info) def __str__(self): json_value = {'name': self.name, 'url': self.url, 'members': self.members, + 'projects': self.projects } return json.dumps(json_value, indent=2) From c44a05632219102ee80fcd16da17bafdba88b991 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 17:49:10 -0400 Subject: [PATCH 09/18] hid api_key + version changes --- roboflow/core/project.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index c76dc0f5..7b19198f 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -14,7 +14,7 @@ #version class that should return class Project(): def __init__(self, api_key, a_project): - self.api_key = api_key + self.__api_key = api_key self.annotation = a_project['annotation'] self.classes = a_project['classes'] self.colors = a_project['colors'] @@ -33,13 +33,13 @@ def __init__(self, api_key, a_project): self.__project_name = temp[1] def get_version_information(self): - dataset_info = requests.get(API_URL + "/" + self.__workspace + "/" + self.__project_name + "?api_key=" + self.api_key) + dataset_info = requests.get(API_URL + "/" + self.__workspace + "/" + self.__project_name + "?api_key=" + self.__api_key) # Throw error if dataset isn't valid/user doesn't have permissions to access the dataset if dataset_info.status_code != 200: raise RuntimeError(dataset_info.text) - dataset_info = dataset_info.json()['project'] + dataset_info = dataset_info.json() return dataset_info['versions'] def list_versions(self): @@ -50,7 +50,7 @@ def versions(self): version_info = self.get_version_information() version_array = [] for a_version in version_info: - version_object = Version(a_version, (self.type if 'model' in a_version else None), self.api_key, self.name, a_version['id'], local=False) + version_object = Version(a_version, (self.type if 'model' in a_version else None), self.__api_key, self.name, a_version['id'], local=False) version_array.append(version_object) return version_array @@ -62,7 +62,7 @@ def version(self, version_number): current_version_num = os.path.basename(version_object['id']) if current_version_num == version_number: - vers = Version(version_object, self.type, self.api_key, self.name, current_version_num, local=False) + vers = Version(version_object, self.type, self.__api_key, self.name, current_version_num, local=False) return vers raise RuntimeError("Version number {} is not found.".format(version_number)) @@ -76,7 +76,7 @@ def __image_upload(self, image_path, hosted_image=False, split="train"): # Construct URL for local image upload self.image_upload_url = "".join([ "https://api.roboflow.com/dataset/", project_name, "/upload", - "?api_key=", self.api_key, + "?api_key=", self.__api_key, "&name=" + image_name, "&split=" + split ]) @@ -103,7 +103,7 @@ def __image_upload(self, image_path, hosted_image=False, split="train"): # Hosted image upload url upload_url = "".join([ "https://api.roboflow.com/dataset/" + self.name + "/upload", - "?api_key=" + self.api_key, + "?api_key=" + self.__api_key, "&name=" + os.path.basename(image_path), "&split=" + split, "&image=" + urllib.parse.quote_plus(image_path) @@ -120,7 +120,7 @@ def __annotation_upload(self, annotation_path, image_id): # Set annotation upload url self.annotation_upload_url = "".join([ "https://api.roboflow.com/dataset/", self.name, "/annotate/", image_id, - "?api_key=", self.api_key, + "?api_key=", self.__api_key, "&name=" + os.path.basename(annotation_path) ]) # Get annotation response From ba95268661afd3900c65fa44b11fa316a6979304 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 17:49:47 -0400 Subject: [PATCH 10/18] hid api_key in version.py --- roboflow/core/version.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roboflow/core/version.py b/roboflow/core/version.py index 75717273..33aa2c1d 100644 --- a/roboflow/core/version.py +++ b/roboflow/core/version.py @@ -6,7 +6,7 @@ class Version(): def __init__(self, version_dict, type, api_key, dataset_slug, version, local): - self.api_key = api_key + self.__api_key = api_key self.name = dataset_slug self.version = version self.type = type @@ -20,9 +20,9 @@ def __init__(self, version_dict, type, api_key, dataset_slug, version, local): version_without_workspace = os.path.basename(version) if self.type == "object-detection": - self.model = ObjectDetectionModel(self.api_key, self.name, version_without_workspace, local=local) + self.model = ObjectDetectionModel(self.__api_key, self.name, version_without_workspace, local=local) elif self.type == "classification": - self.model = ClassificationModel(self.api_key, self.name, version_without_workspace, local=local) + self.model = ClassificationModel(self.__api_key, self.name, version_without_workspace, local=local) else: self.model = None From aecb18e9fb11dcf9e2dafc4e6d192d54a8f19051 Mon Sep 17 00:00:00 2001 From: Brad Dwyer Date: Mon, 13 Sep 2021 17:09:20 -0500 Subject: [PATCH 11/18] Allow optionally re-stating the workspace in the project id --- roboflow/core/workspace.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/roboflow/core/workspace.py b/roboflow/core/workspace.py index 813a2990..50fae869 100644 --- a/roboflow/core/workspace.py +++ b/roboflow/core/workspace.py @@ -27,9 +27,9 @@ def projects(self): def project(self, project_name): - + project_name = project_name.replace(self.url + "/", "") if "/" in project_name: - raise RuntimeError("Do not re-specify the workspace {} in your project request".format(project_name.rsplit()[0])) + raise RuntimeError("The {} project is not available in this ({}) workspace".format(project_name, self.url)) dataset_info = requests.get(API_URL + "/" + self.url + "/" + project_name + "?api_key=" + self.__api_key) @@ -49,4 +49,3 @@ def __str__(self): } return json.dumps(json_value, indent=2) - From e16ddae138ae1315eeeb65423cc2b68b61267f6e Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Mon, 13 Sep 2021 18:26:26 -0400 Subject: [PATCH 12/18] version number can be int --- roboflow/core/project.py | 2 +- roboflow/core/workspace.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index 7b19198f..3106ca47 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -61,7 +61,7 @@ def version(self, version_number): for version_object in version_info: current_version_num = os.path.basename(version_object['id']) - if current_version_num == version_number: + if current_version_num == str(version_number): vers = Version(version_object, self.type, self.__api_key, self.name, current_version_num, local=False) return vers diff --git a/roboflow/core/workspace.py b/roboflow/core/workspace.py index 50fae869..1ec7ba20 100644 --- a/roboflow/core/workspace.py +++ b/roboflow/core/workspace.py @@ -28,6 +28,7 @@ def projects(self): def project(self, project_name): project_name = project_name.replace(self.url + "/", "") + if "/" in project_name: raise RuntimeError("The {} project is not available in this ({}) workspace".format(project_name, self.url)) From ac4ab8f6edf143d25edeaecb0afe0b97eb14c713 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Tue, 14 Sep 2021 01:06:43 -0400 Subject: [PATCH 13/18] added __str__ to models --- roboflow/models/classification.py | 8 ++++++++ roboflow/models/object_detection.py | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/roboflow/models/classification.py b/roboflow/models/classification.py index d6692951..afa2b06e 100644 --- a/roboflow/models/classification.py +++ b/roboflow/models/classification.py @@ -2,6 +2,7 @@ import io import os import urllib +import json import requests from PIL import Image @@ -102,3 +103,10 @@ def __exception_check(self, image_path_check=None): if image_path_check is not None: if not os.path.exists(image_path_check) and not check_image_url(image_path_check): raise Exception("Image does not exist at " + image_path_check + "!") + + def __str__(self): + json_value = {'name': self.dataset_slug, + 'version': self.version, + 'base_url': self.base_url} + + return json.dumps(json_value, indent=2) diff --git a/roboflow/models/object_detection.py b/roboflow/models/object_detection.py index ae250124..47a6ddc1 100644 --- a/roboflow/models/object_detection.py +++ b/roboflow/models/object_detection.py @@ -5,6 +5,7 @@ import requests import urllib from PIL import Image +import json from roboflow.config import OBJECT_DETECTION_MODEL from roboflow.util.prediction import PredictionGroup @@ -172,3 +173,15 @@ def __generate_url(self, local=None, classes=None, overlap=None, confidence=None # add classes parameter to api if self.classes is not None: self.api_url += "&classes=" + self.classes + def __str__(self): + json_value = {'name': self.dataset_slug, + 'version': self.version, + 'classes': self.classes, + 'overlap': self.overlap, + 'confidence': self.confidence, + 'stroke': self.stroke, + 'labels': self.labels, + 'format': self.format, + 'base_url': self.base_url} + + return json.dumps(json_value, indent=2) From 80a0a106d2390924886887f9c1ea1f8d1d902c9c Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Tue, 14 Sep 2021 09:40:28 -0400 Subject: [PATCH 14/18] fixed prediction bug --- roboflow/core/version.py | 4 ++-- roboflow/models/classification.py | 7 +++++-- roboflow/models/object_detection.py | 6 ++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/roboflow/core/version.py b/roboflow/core/version.py index 33aa2c1d..b7f22032 100644 --- a/roboflow/core/version.py +++ b/roboflow/core/version.py @@ -20,9 +20,9 @@ def __init__(self, version_dict, type, api_key, dataset_slug, version, local): version_without_workspace = os.path.basename(version) if self.type == "object-detection": - self.model = ObjectDetectionModel(self.__api_key, self.name, version_without_workspace, local=local) + self.model = ObjectDetectionModel(self.__api_key, self.id, self.name, version_without_workspace, local=local) elif self.type == "classification": - self.model = ClassificationModel(self.__api_key, self.name, version_without_workspace, local=local) + self.model = ClassificationModel(self.__api_key, self.id, self.name, version_without_workspace, self.id, local=local) else: self.model = None diff --git a/roboflow/models/classification.py b/roboflow/models/classification.py index afa2b06e..5bf56be8 100644 --- a/roboflow/models/classification.py +++ b/roboflow/models/classification.py @@ -13,7 +13,7 @@ class ClassificationModel: - def __init__(self, api_key, dataset_slug=None, version=None, local=False): + def __init__(self, api_key, id, dataset_slug=None, version=None, local=False): """ :param api_key: @@ -22,6 +22,7 @@ def __init__(self, api_key, dataset_slug=None, version=None, local=False): """ # Instantiate different API URL parameters self.api_key = api_key + self.id=id self.dataset_slug = dataset_slug self.version = version if not local: @@ -87,7 +88,9 @@ def __generate_url(self): """ # Generates URL based on all parameters - without_workspace = os.path.basename(self.dataset_slug) + splitted = self.id.rsplit("/") + without_workspace = splitted[1] + self.api_url = "".join([ self.base_url + without_workspace + '/' + str(self.version), "?api_key=" + self.api_key, diff --git a/roboflow/models/object_detection.py b/roboflow/models/object_detection.py index 47a6ddc1..d86a71d6 100644 --- a/roboflow/models/object_detection.py +++ b/roboflow/models/object_detection.py @@ -14,7 +14,7 @@ class ObjectDetectionModel: - def __init__(self, api_key, dataset_slug=None, version=None, local=False, classes=None, overlap=30, confidence=40, + def __init__(self, api_key, id, dataset_slug=None, version=None, local=False, classes=None, overlap=30, confidence=40, stroke=1, labels=False, format="json"): """ From Roboflow Docs: @@ -41,6 +41,7 @@ def __init__(self, api_key, dataset_slug=None, version=None, local=False, classe # Instantiate different API URL parameters # To be moved to predict self.api_key = api_key + self.id = id self.dataset_slug = dataset_slug self.version = version self.classes = classes @@ -158,7 +159,8 @@ def __generate_url(self, local=None, classes=None, overlap=None, confidence=None self.format = format # Create the new API URL - without_workspace = os.path.basename(self.dataset_slug) + splitted = self.id.rsplit("/") + without_workspace = splitted[1] self.api_url = "".join([ self.base_url + without_workspace + '/' + str(self.version), From 563d0f640a974d907535466c35d9c448ac4b7b9a Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Tue, 14 Sep 2021 09:45:06 -0400 Subject: [PATCH 15/18] protected api key --- roboflow/core/project.py | 10 +++++++--- roboflow/models/classification.py | 4 ++-- roboflow/models/object_detection.py | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index 3106ca47..34559385 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -71,9 +71,12 @@ def __image_upload(self, image_path, hosted_image=False, split="train"): # If image is not a hosted image if not hosted_image: - project_name = os.path.basename(self.name) + + project_name = self.id.rsplit("/")[1] image_name = os.path.basename(image_path) + # Construct URL for local image upload + self.image_upload_url = "".join([ "https://api.roboflow.com/dataset/", project_name, "/upload", "?api_key=", self.__api_key, @@ -101,8 +104,10 @@ def __image_upload(self, image_path, hosted_image=False, split="train"): else: # Hosted image upload url + project_name = self.id.rsplit("/")[1] + upload_url = "".join([ - "https://api.roboflow.com/dataset/" + self.name + "/upload", + "https://api.roboflow.com/dataset/" + self.project_name + "/upload", "?api_key=" + self.__api_key, "&name=" + os.path.basename(image_path), "&split=" + split, @@ -136,7 +141,6 @@ def upload(self, image_path=None, annotation_path=None, hosted_image=False, imag if image_path is not None: # Upload Image Response response = self.__image_upload(image_path, hosted_image=hosted_image, split=split) - # Get JSON response values try: success, image_id = response.json()['success'], response.json()['id'] diff --git a/roboflow/models/classification.py b/roboflow/models/classification.py index 5bf56be8..7d992f0a 100644 --- a/roboflow/models/classification.py +++ b/roboflow/models/classification.py @@ -21,7 +21,7 @@ def __init__(self, api_key, id, dataset_slug=None, version=None, local=False): :param version: """ # Instantiate different API URL parameters - self.api_key = api_key + self.__api_key = api_key self.id=id self.dataset_slug = dataset_slug self.version = version @@ -93,7 +93,7 @@ def __generate_url(self): self.api_url = "".join([ self.base_url + without_workspace + '/' + str(self.version), - "?api_key=" + self.api_key, + "?api_key=" + self.__api_key, "&name=YOUR_IMAGE.jpg"]) def __exception_check(self, image_path_check=None): diff --git a/roboflow/models/object_detection.py b/roboflow/models/object_detection.py index d86a71d6..b8a6b0fd 100644 --- a/roboflow/models/object_detection.py +++ b/roboflow/models/object_detection.py @@ -40,7 +40,7 @@ def __init__(self, api_key, id, dataset_slug=None, version=None, local=False, cl """ # Instantiate different API URL parameters # To be moved to predict - self.api_key = api_key + self.__api_key = api_key self.id = id self.dataset_slug = dataset_slug self.version = version @@ -164,7 +164,7 @@ def __generate_url(self, local=None, classes=None, overlap=None, confidence=None self.api_url = "".join([ self.base_url + without_workspace + '/' + str(self.version), - "?api_key=" + self.api_key, + "?api_key=" + self.__api_key, "&name=YOUR_IMAGE.jpg", "&overlap=" + str(self.overlap), "&confidence=" + str(self.confidence), From e6b60d36b994113bda19a14f5b8dc56d7d56f0a3 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Tue, 14 Sep 2021 11:39:53 -0400 Subject: [PATCH 16/18] replaced dataset_slug with name() --- roboflow/core/project.py | 2 +- roboflow/core/version.py | 4 ++-- roboflow/models/classification.py | 16 ++++++++-------- roboflow/models/object_detection.py | 14 +++++++------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index 34559385..0bb97be9 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -178,7 +178,7 @@ def upload(self, image_path=None, annotation_path=None, hosted_image=False, imag def __str__(self): # String representation of project json_str = { - "dataset_slug": self.name, + "name": self.name, "type": self.type, "workspace": self.__workspace, } diff --git a/roboflow/core/version.py b/roboflow/core/version.py index b7f22032..a5f5d308 100644 --- a/roboflow/core/version.py +++ b/roboflow/core/version.py @@ -5,9 +5,9 @@ class Version(): - def __init__(self, version_dict, type, api_key, dataset_slug, version, local): + def __init__(self, version_dict, type, api_key, name, version, local): self.__api_key = api_key - self.name = dataset_slug + self.name = name self.version = version self.type = type self.augmentation = version_dict['augmentation'] diff --git a/roboflow/models/classification.py b/roboflow/models/classification.py index 7d992f0a..210a9afd 100644 --- a/roboflow/models/classification.py +++ b/roboflow/models/classification.py @@ -13,24 +13,24 @@ class ClassificationModel: - def __init__(self, api_key, id, dataset_slug=None, version=None, local=False): + def __init__(self, api_key, id, name=None, version=None, local=False): """ :param api_key: - :param dataset_slug: + :param name: :param version: """ # Instantiate different API URL parameters self.__api_key = api_key self.id=id - self.dataset_slug = dataset_slug + self.name = name self.version = version if not local: self.base_url = "https://classify.roboflow.com/" else: self.base_url = "http://localhost:9001/" - if dataset_slug is not None and version is not None: + if self.name is not None and version is not None: self.__generate_url() def predict(self, image_path, hosted=False): @@ -69,15 +69,15 @@ def predict(self, image_path, hosted=False): image_path=image_path, prediction_type=CLASSIFICATION_MODEL) - def load_model(self, dataset_slug, version): + def load_model(self, name, version): """ - :param dataset_slug: + :param name: :param version: :return: """ # Load model based on user defined characteristics - self.dataset_slug = dataset_slug + self.name = name self.version = version self.__generate_url() @@ -108,7 +108,7 @@ def __exception_check(self, image_path_check=None): raise Exception("Image does not exist at " + image_path_check + "!") def __str__(self): - json_value = {'name': self.dataset_slug, + json_value = {'name': self.name, 'version': self.version, 'base_url': self.base_url} diff --git a/roboflow/models/object_detection.py b/roboflow/models/object_detection.py index b8a6b0fd..219a3932 100644 --- a/roboflow/models/object_detection.py +++ b/roboflow/models/object_detection.py @@ -14,13 +14,13 @@ class ObjectDetectionModel: - def __init__(self, api_key, id, dataset_slug=None, version=None, local=False, classes=None, overlap=30, confidence=40, + def __init__(self, api_key, id, name=None, version=None, local=False, classes=None, overlap=30, confidence=40, stroke=1, labels=False, format="json"): """ From Roboflow Docs: :param api_key: Your API key (obtained via your workspace API settings page) - :param dataset_slug: The url-safe version of the dataset name. You can find it in the web UI by looking at + :param name: The url-safe version of the dataset name. You can find it in the web UI by looking at the URL on the main project view or by clicking the "Get curl command" button in the train results section of your dataset version after training your model. :param local: Boolean value dictating whether to use the local server or hosted API @@ -42,7 +42,7 @@ def __init__(self, api_key, id, dataset_slug=None, version=None, local=False, cl # To be moved to predict self.__api_key = api_key self.id = id - self.dataset_slug = dataset_slug + self.name = name self.version = version self.classes = classes self.overlap = overlap @@ -58,10 +58,10 @@ def __init__(self, api_key, id, dataset_slug=None, version=None, local=False, cl self.base_url = "http://localhost:9001/" # If dataset slug not none, instantiate API URL - if dataset_slug is not None and version is not None: + if name is not None and version is not None: self.__generate_url() - def load_model(self, dataset_slug, version, local=None, classes=None, overlap=None, confidence=None, + def load_model(self, name, version, local=None, classes=None, overlap=None, confidence=None, stroke=None, labels=None, format=None): """ Loads a Model based on a Model Endpoint @@ -69,7 +69,7 @@ def load_model(self, dataset_slug, version, local=None, classes=None, overlap=No :param model_endpoint: This is the endpoint that is loaded into the api_url """ # To load a model manually, they must specify a dataset slug - self.dataset_slug = dataset_slug + self.name = name self.version = version # Generate URL based on parameters self.__generate_url(local=local, classes=classes, overlap=overlap, confidence=confidence, @@ -176,7 +176,7 @@ def __generate_url(self, local=None, classes=None, overlap=None, confidence=None if self.classes is not None: self.api_url += "&classes=" + self.classes def __str__(self): - json_value = {'name': self.dataset_slug, + json_value = {'name': self.name, 'version': self.version, 'classes': self.classes, 'overlap': self.overlap, From a4a83eb2c68d29bdceb6d6766df7f02b9689aa09 Mon Sep 17 00:00:00 2001 From: Brad Dwyer Date: Tue, 14 Sep 2021 10:47:46 -0500 Subject: [PATCH 17/18] Add the model ID --- roboflow/models/object_detection.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/roboflow/models/object_detection.py b/roboflow/models/object_detection.py index b8a6b0fd..27423969 100644 --- a/roboflow/models/object_detection.py +++ b/roboflow/models/object_detection.py @@ -176,14 +176,21 @@ def __generate_url(self, local=None, classes=None, overlap=None, confidence=None if self.classes is not None: self.api_url += "&classes=" + self.classes def __str__(self): - json_value = {'name': self.dataset_slug, - 'version': self.version, - 'classes': self.classes, - 'overlap': self.overlap, - 'confidence': self.confidence, - 'stroke': self.stroke, - 'labels': self.labels, - 'format': self.format, - 'base_url': self.base_url} + # Create the new API URL + splitted = self.id.rsplit("/") + without_workspace = splitted[1] + + json_value = { + 'id': without_workspace + '/' + str(self.version), + 'name': self.dataset_slug, + 'version': self.version, + 'classes': self.classes, + 'overlap': self.overlap, + 'confidence': self.confidence, + 'stroke': self.stroke, + 'labels': self.labels, + 'format': self.format, + 'base_url': self.base_url + } return json.dumps(json_value, indent=2) From c46a26c142a6992ae1aa86f71efdc4afb5d8a4d9 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Tue, 14 Sep 2021 12:17:53 -0400 Subject: [PATCH 18/18] Update requirements.txt --- requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index f83e4510..422e6cd8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,13 +3,13 @@ chardet==4.0.0 cycler==0.10.0 idna==2.10 kiwisolver==1.3.1 -matplotlib==3.3.4 +matplotlib numpy==1.19.5 opencv-python==4.5.3.56 -Pillow==8.3.0 +Pillow pyparsing==2.4.7 -python-dateutil==2.8.1 +python-dateutil python-dotenv==0.18.0 requests==2.25.1 -six==1.16.0 +six urllib3==1.26.6