Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion roboflow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ 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'])
return Project(self.api_key, dataset_info)

def __str__(self):
json_value = {'api_key': self.api_key,
Expand Down
62 changes: 37 additions & 25 deletions roboflow/core/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
import os
import urllib
import datetime
import warnings
import cv2
import requests
Expand All @@ -12,25 +13,33 @@

#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
self.workspace = workspace
self.all_versions = []
def __init__(self, api_key, a_project):
self.__api_key = api_key
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):

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.__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):
Expand All @@ -41,9 +50,8 @@ 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.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):
Expand All @@ -53,8 +61,8 @@ 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:
vers = Version(self.category, self.api_key, self.name, current_version_num, local=False)
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

raise RuntimeError("Version number {} is not found.".format(version_number))
Expand All @@ -63,12 +71,15 @@ 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,
"?api_key=", self.__api_key,
"&name=" + image_name,
"&split=" + split
])
Expand All @@ -93,9 +104,11 @@ 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",
"?api_key=" + self.api_key,
"https://api.roboflow.com/dataset/" + self.project_name + "/upload",
"?api_key=" + self.__api_key,
"&name=" + os.path.basename(image_path),
"&split=" + split,
"&image=" + urllib.parse.quote_plus(image_path)
Expand All @@ -112,7 +125,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
Expand All @@ -128,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']
Expand Down Expand Up @@ -166,9 +178,9 @@ 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,
"task_type": self.category,
"workspace": self.workspace
"name": self.name,
"type": self.type,
"workspace": self.__workspace,
}

return json.dumps(json_str, indent=2)
37 changes: 22 additions & 15 deletions roboflow/core/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,34 @@


class Version():
def __init__(self, type, api_key, dataset_slug, version, local):
self.api_key = api_key
self.name = dataset_slug
def __init__(self, version_dict, type, api_key, name, version, local):
self.__api_key = api_key
self.name = name
self.version = version
self.category = type
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)

if self.category == "object-detection":
self.model = ObjectDetectionModel(self.api_key, self.name, version_without_workspace, local=local)
elif self.category == "classification":
self.model = ClassificationModel(self.api_key, self.name, version_without_workspace, local=local)
if self.type == "object-detection":
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.id, self.name, version_without_workspace, self.id, local=local)
else:
self.model = None

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)



34 changes: 20 additions & 14 deletions roboflow/core/workspace.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@
import requests
import json
from roboflow.core.project import Project
from roboflow.config import *

class Workspace():
def __init__(self, info, api_key, default_workspace):

self.api_key = api_key
self.name = default_workspace

workspace_info = info['workspace']
self.name = workspace_info['name']
self.project_list = workspace_info['projects']
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.__api_key = api_key


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


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.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']

return Project(self.api_key, dataset_info['id'], dataset_info['type'], dataset_info['versions'])
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)
31 changes: 21 additions & 10 deletions roboflow/models/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import io
import os
import urllib
import json

import requests
from PIL import Image
Expand All @@ -12,23 +13,24 @@


class ClassificationModel:
def __init__(self, api_key, 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.dataset_slug = dataset_slug
self.__api_key = api_key
self.id=id
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):
Expand Down Expand Up @@ -67,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()

Expand All @@ -86,10 +88,12 @@ 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,
"?api_key=" + self.__api_key,
"&name=YOUR_IMAGE.jpg"])

def __exception_check(self, image_path_check=None):
Expand All @@ -102,3 +106,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.name,
'version': self.version,
'base_url': self.base_url}

return json.dumps(json_value, indent=2)
Loading