roboflow-slim 1.3.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. roboflow/__init__.py +285 -0
  2. roboflow/adapters/__init__.py +0 -0
  3. roboflow/adapters/deploymentapi.py +119 -0
  4. roboflow/adapters/rfapi.py +807 -0
  5. roboflow/adapters/vision_events_api.py +260 -0
  6. roboflow/cli/__init__.py +402 -0
  7. roboflow/cli/_compat.py +79 -0
  8. roboflow/cli/_output.py +193 -0
  9. roboflow/cli/_resolver.py +137 -0
  10. roboflow/cli/_table.py +79 -0
  11. roboflow/cli/handlers/__init__.py +8 -0
  12. roboflow/cli/handlers/_aliases.py +191 -0
  13. roboflow/cli/handlers/annotation.py +275 -0
  14. roboflow/cli/handlers/auth.py +281 -0
  15. roboflow/cli/handlers/batch.py +63 -0
  16. roboflow/cli/handlers/completion.py +65 -0
  17. roboflow/cli/handlers/deployment.py +305 -0
  18. roboflow/cli/handlers/folder.py +202 -0
  19. roboflow/cli/handlers/image.py +473 -0
  20. roboflow/cli/handlers/infer.py +117 -0
  21. roboflow/cli/handlers/model.py +204 -0
  22. roboflow/cli/handlers/project.py +200 -0
  23. roboflow/cli/handlers/search.py +121 -0
  24. roboflow/cli/handlers/train.py +204 -0
  25. roboflow/cli/handlers/universe.py +61 -0
  26. roboflow/cli/handlers/version.py +327 -0
  27. roboflow/cli/handlers/video.py +107 -0
  28. roboflow/cli/handlers/vision_events.py +441 -0
  29. roboflow/cli/handlers/workflow.py +405 -0
  30. roboflow/cli/handlers/workspace.py +240 -0
  31. roboflow/config.py +93 -0
  32. roboflow/core/__init__.py +0 -0
  33. roboflow/core/dataset.py +10 -0
  34. roboflow/core/model.py +14 -0
  35. roboflow/core/project.py +1043 -0
  36. roboflow/core/version.py +685 -0
  37. roboflow/core/workspace.py +1273 -0
  38. roboflow/deployment.py +330 -0
  39. roboflow/models/__init__.py +2 -0
  40. roboflow/models/classification.py +186 -0
  41. roboflow/models/clip.py +16 -0
  42. roboflow/models/gaze.py +17 -0
  43. roboflow/models/inference.py +416 -0
  44. roboflow/models/instance_segmentation.py +67 -0
  45. roboflow/models/keypoint_detection.py +192 -0
  46. roboflow/models/object_detection.py +551 -0
  47. roboflow/models/semantic_segmentation.py +50 -0
  48. roboflow/models/video.py +240 -0
  49. roboflow/roboflowpy.py +20 -0
  50. roboflow/util/__init__.py +0 -0
  51. roboflow/util/active_learning_utils.py +69 -0
  52. roboflow/util/annotations.py +13 -0
  53. roboflow/util/clip_compare_utils.py +44 -0
  54. roboflow/util/folderparser.py +405 -0
  55. roboflow/util/general.py +67 -0
  56. roboflow/util/image_utils.py +118 -0
  57. roboflow/util/model_processor.py +452 -0
  58. roboflow/util/prediction.py +529 -0
  59. roboflow/util/two_stage_utils.py +29 -0
  60. roboflow/util/versions.py +134 -0
  61. roboflow_slim-1.3.3.dist-info/METADATA +299 -0
  62. roboflow_slim-1.3.3.dist-info/RECORD +99 -0
  63. roboflow_slim-1.3.3.dist-info/WHEEL +5 -0
  64. roboflow_slim-1.3.3.dist-info/entry_points.txt +2 -0
  65. roboflow_slim-1.3.3.dist-info/licenses/LICENSE +201 -0
  66. roboflow_slim-1.3.3.dist-info/top_level.txt +2 -0
  67. tests/adapters/__init__.py +0 -0
  68. tests/adapters/test_rfapi_phase2.py +544 -0
  69. tests/cli/__init__.py +0 -0
  70. tests/cli/test_annotation_handler.py +255 -0
  71. tests/cli/test_auth.py +68 -0
  72. tests/cli/test_backwards_compat.py +72 -0
  73. tests/cli/test_batch_handler.py +38 -0
  74. tests/cli/test_completion_handler.py +34 -0
  75. tests/cli/test_deployment_handler.py +87 -0
  76. tests/cli/test_discovery.py +129 -0
  77. tests/cli/test_folder_handler.py +193 -0
  78. tests/cli/test_image_handler.py +329 -0
  79. tests/cli/test_infer_handler.py +153 -0
  80. tests/cli/test_model_handler.py +246 -0
  81. tests/cli/test_output.py +166 -0
  82. tests/cli/test_project_handler.py +42 -0
  83. tests/cli/test_search_handler.py +33 -0
  84. tests/cli/test_train_handler.py +147 -0
  85. tests/cli/test_universe_handler.py +85 -0
  86. tests/cli/test_version_handler.py +117 -0
  87. tests/cli/test_video_handler.py +64 -0
  88. tests/cli/test_workflow_handler.py +390 -0
  89. tests/cli/test_workspace.py +196 -0
  90. tests/models/__init__.py +0 -0
  91. tests/models/test_instance_segmentation.py +164 -0
  92. tests/models/test_keypoint_detection.py +70 -0
  93. tests/models/test_object_detection.py +153 -0
  94. tests/models/test_semantic_segmentation.py +128 -0
  95. tests/util/__init__.py +0 -0
  96. tests/util/dummy_module/__init__.py +1 -0
  97. tests/util/test_folderparser.py +212 -0
  98. tests/util/test_image_utils.py +42 -0
  99. tests/util/test_versions.py +43 -0
roboflow/__init__.py ADDED
@@ -0,0 +1,285 @@
1
+ import json
2
+ import os
3
+ import sys
4
+ import time
5
+ from getpass import getpass
6
+ from pathlib import Path
7
+ from urllib.parse import urlparse
8
+
9
+ import requests
10
+
11
+ from roboflow.adapters import rfapi
12
+ from roboflow.config import API_URL, APP_URL, DEMO_KEYS, load_roboflow_api_key
13
+ from roboflow.core.workspace import Workspace
14
+ from roboflow.util.general import write_line
15
+
16
+ try:
17
+ from roboflow.core.project import Project
18
+ from roboflow.models import CLIPModel, GazeModel # noqa: F401
19
+ except ImportError:
20
+ Project = None # type: ignore[assignment,misc]
21
+ CLIPModel = None # type: ignore[assignment,misc]
22
+ GazeModel = None # type: ignore[assignment,misc]
23
+
24
+ __version__ = "1.3.3"
25
+
26
+
27
+ def check_key(api_key, model, notebook, num_retries=0):
28
+ if not isinstance(api_key, str):
29
+ raise RuntimeError(
30
+ "API Key is of Incorrect Type \n Expected Type: " + str(str) + "\n Input Type: " + str(type(api_key))
31
+ )
32
+
33
+ if any(c for c in api_key if c.islower()): # check if any of the api key characters are lowercase
34
+ if api_key in DEMO_KEYS:
35
+ # passthrough for public download of COCO-128 for the time being
36
+ return api_key
37
+ else:
38
+ # validate key normally
39
+ response = requests.post(API_URL + "/?api_key=" + api_key)
40
+
41
+ if response.status_code == 401:
42
+ raise RuntimeError(response.text)
43
+
44
+ if response.status_code != 200:
45
+ # retry 5 times
46
+ if num_retries < 5:
47
+ print("retrying...")
48
+ time.sleep(1)
49
+ num_retries += 1
50
+ return check_key(api_key, model, notebook, num_retries)
51
+ else:
52
+ raise RuntimeError("There was an error validating the api key with Roboflow server.")
53
+ else:
54
+ r = response.json()
55
+ return r
56
+ else: # then you're using a dummy key
57
+ sys.stdout.write(
58
+ "upload and label your dataset, and get an API KEY here: "
59
+ + APP_URL
60
+ + "/?model="
61
+ + model
62
+ + "&ref="
63
+ + notebook
64
+ + "\n"
65
+ )
66
+ return "onboarding"
67
+
68
+
69
+ def login(workspace=None, force=False):
70
+ os_name = os.name
71
+
72
+ if os_name == "nt":
73
+ default_path = str(Path.home() / "roboflow" / "config.json")
74
+ else:
75
+ default_path = str(Path.home() / ".config" / "roboflow" / "config.json")
76
+
77
+ # default configuration location
78
+ conf_location = os.getenv("ROBOFLOW_CONFIG_DIR", default=default_path)
79
+ if os.path.isfile(conf_location) and not force:
80
+ write_line("You are already logged into Roboflow. To make a different login,run roboflow.login(force=True).")
81
+ return None
82
+ # we could eventually return the workspace object here
83
+ # return Roboflow().workspace()
84
+ elif os.path.isfile(conf_location) and force:
85
+ os.remove(conf_location)
86
+
87
+ if workspace is None:
88
+ write_line("visit " + APP_URL + "/auth-cli to get your authentication token.")
89
+ else:
90
+ write_line("visit " + APP_URL + "/auth-cli/?workspace=" + workspace + " to get your authentication token.")
91
+
92
+ token = getpass("Paste the authentication token here: ")
93
+
94
+ r_login = requests.get(APP_URL + "/query/cliAuthToken/" + token)
95
+
96
+ if r_login.status_code == 200:
97
+ r_login = r_login.json()
98
+ if r_login is None:
99
+ raise ValueError("Invalid API key. Please check your API key and try again.")
100
+
101
+ # make config directory if it doesn't exist
102
+ if not os.path.exists(os.path.dirname(conf_location)):
103
+ os.makedirs(os.path.dirname(conf_location))
104
+
105
+ r_login = {"workspaces": r_login}
106
+ # set first workspace as default workspace
107
+
108
+ default_workspace_id = list(r_login["workspaces"].keys())[0]
109
+ workspace = r_login["workspaces"][default_workspace_id]
110
+ r_login["RF_WORKSPACE"] = workspace["url"]
111
+
112
+ # write config file
113
+ with open(conf_location, "w") as f:
114
+ json.dump(r_login, f, indent=2)
115
+
116
+ else:
117
+ r_login.raise_for_status()
118
+
119
+ return None
120
+ # we could eventually return the workspace object here
121
+ # return Roboflow().workspace()
122
+
123
+
124
+ active_workspace = None
125
+
126
+
127
+ def initialize_roboflow(the_workspace=None):
128
+ """High level function to initialize Roboflow.
129
+
130
+ Args:
131
+ the_workspace: the workspace url to initialize.
132
+ If None, the default workspace will be used.
133
+
134
+ Returns:
135
+ None
136
+ """
137
+
138
+ global active_workspace
139
+
140
+ if the_workspace is None:
141
+ active_workspace = Roboflow().workspace()
142
+ else:
143
+ active_workspace = Roboflow().workspace(the_workspace)
144
+
145
+ return active_workspace
146
+
147
+
148
+ def load_model(model_url):
149
+ """High level function to load Roboflow models.
150
+
151
+ Args:
152
+ model_url: the model url to load.
153
+ Must be from either app.roboflow.com or universe.roboflow.com
154
+
155
+ Returns:
156
+ the model object to use for inference
157
+ """
158
+
159
+ operate_workspace = initialize_roboflow()
160
+
161
+ if "universe.roboflow.com" in model_url or "app.roboflow.com" in model_url:
162
+ parsed_url = urlparse(model_url)
163
+ path_parts = parsed_url.path.split("/")
164
+ project = path_parts[2]
165
+ version = int(path_parts[-1])
166
+ else:
167
+ raise ValueError("Model URL must be from either app.roboflow.com or universe.roboflow.com")
168
+
169
+ project = operate_workspace.project(project)
170
+ version = project.version(version)
171
+ model = version.model
172
+ return model
173
+
174
+
175
+ def download_dataset(dataset_url, model_format, location=None):
176
+ """High level function to download data from Roboflow.
177
+
178
+ Args:
179
+ dataset_url: the dataset url to download.
180
+ Must be from either app.roboflow.com or universe.roboflow.com
181
+ model_format: the format the dataset will be downloaded in
182
+ location: the location the dataset will be downloaded to
183
+
184
+ Returns:
185
+ The dataset object with location available as dataset.location
186
+ """
187
+
188
+ if "universe.roboflow.com" in dataset_url or "app.roboflow.com" in dataset_url:
189
+ parsed_url = urlparse(dataset_url)
190
+ path_parts = parsed_url.path.split("/")
191
+ project = path_parts[2]
192
+ version = int(path_parts[-1])
193
+ the_workspace = path_parts[1]
194
+ else:
195
+ raise ValueError("Model URL must be from either app.roboflow.com or universe.roboflow.com")
196
+ operate_workspace = initialize_roboflow(the_workspace=the_workspace)
197
+
198
+ project = operate_workspace.project(project)
199
+ version = project.version(version)
200
+ return version.download(model_format, location)
201
+
202
+
203
+ # continue distributing this object for back compatibility
204
+ class Roboflow:
205
+ def __init__(
206
+ self,
207
+ api_key=None,
208
+ model_format="undefined",
209
+ notebook="undefined",
210
+ ):
211
+ self.api_key = api_key
212
+ if self.api_key is None:
213
+ self.api_key = load_roboflow_api_key()
214
+
215
+ self.model_format = model_format
216
+ self.notebook = notebook
217
+ self.onboarding = False
218
+ self.auth()
219
+
220
+ def auth(self):
221
+ r = check_key(self.api_key, self.model_format, self.notebook)
222
+
223
+ if r == "onboarding":
224
+ self.onboarding = True
225
+ return self
226
+ elif r in DEMO_KEYS:
227
+ self.universe = True
228
+ return self
229
+ else:
230
+ w = r["workspace"] # type: ignore[arg-type]
231
+ self.current_workspace = w
232
+ return self
233
+
234
+ def workspace(self, the_workspace=None):
235
+ sys.stdout.write("\r" + "loading Roboflow workspace...")
236
+ sys.stdout.write("\n")
237
+ sys.stdout.flush()
238
+
239
+ if the_workspace is None:
240
+ the_workspace = self.current_workspace
241
+
242
+ if self.api_key: # Check if api_key was passed during __init__
243
+ api_key = self.api_key
244
+ list_projects = rfapi.get_workspace(api_key, the_workspace)
245
+ return Workspace(list_projects, api_key, the_workspace, self.model_format)
246
+
247
+ elif self.api_key in DEMO_KEYS:
248
+ return Workspace({}, self.api_key, the_workspace, self.model_format)
249
+
250
+ else:
251
+ raise ValueError("A valid API key must be provided.")
252
+
253
+ def project(self, project_name, the_workspace=None):
254
+ """Function that takes in the name of the project and returns the project object
255
+ :param project_name api_key: project name
256
+ :param the_workspace workspace name
257
+ :return project object
258
+ """
259
+ if Project is None:
260
+ raise ImportError(
261
+ "Project requires additional dependencies. Install the full package: pip install roboflow"
262
+ )
263
+
264
+ if the_workspace is None:
265
+ if "/" in project_name:
266
+ splitted_project = project_name.rsplit("/")
267
+ the_workspace, project_name = splitted_project[0], splitted_project[1]
268
+ else:
269
+ the_workspace = self.current_workspace
270
+
271
+ dataset_info = requests.get(API_URL + "/" + the_workspace + "/" + project_name + "?api_key=" + self.api_key)
272
+
273
+ # Throw error if dataset isn't valid/user doesn't have
274
+ # permissions to access the dataset
275
+ if dataset_info.status_code != 200:
276
+ raise RuntimeError(dataset_info.text)
277
+
278
+ dataset_info = dataset_info.json()["project"]
279
+
280
+ return Project(self.api_key, dataset_info)
281
+
282
+ def __str__(self):
283
+ """to string function"""
284
+ json_value = {"api_key": self.api_key, "workspace": self.workspace}
285
+ return json.dumps(json_value, indent=2)
File without changes
@@ -0,0 +1,119 @@
1
+ import urllib
2
+
3
+ import requests
4
+
5
+ from roboflow.config import DEDICATED_DEPLOYMENT_URL
6
+
7
+
8
+ class DeploymentApiError(Exception):
9
+ pass
10
+
11
+
12
+ def add_deployment(
13
+ api_key, creator_email, machine_type, duration, delete_on_expiration, deployment_name, inference_version
14
+ ):
15
+ url = f"{DEDICATED_DEPLOYMENT_URL}/add"
16
+ params = {
17
+ "api_key": api_key,
18
+ "creator_email": creator_email,
19
+ # "security_level": security_level,
20
+ "duration": duration,
21
+ "delete_on_expiration": delete_on_expiration,
22
+ "deployment_name": deployment_name,
23
+ "inference_version": inference_version,
24
+ }
25
+ if machine_type is not None:
26
+ params["machine_type"] = machine_type
27
+ response = requests.post(url, json=params)
28
+ if response.status_code != 200:
29
+ return response.status_code, response.text
30
+ return response.status_code, response.json()
31
+
32
+
33
+ def get_deployment(api_key, deployment_name):
34
+ url = f"{DEDICATED_DEPLOYMENT_URL}/get?api_key={api_key}&deployment_name={deployment_name}"
35
+ response = requests.get(url)
36
+ if response.status_code != 200:
37
+ return response.status_code, response.text
38
+ return response.status_code, response.json()
39
+
40
+
41
+ def list_deployment(api_key):
42
+ url = f"{DEDICATED_DEPLOYMENT_URL}/list?api_key={api_key}"
43
+ response = requests.get(url)
44
+ if response.status_code != 200:
45
+ return response.status_code, response.text
46
+ return response.status_code, response.json()
47
+
48
+
49
+ def get_workspace_usage(api_key, from_timestamp, to_timestamp):
50
+ params = {"api_key": api_key}
51
+ if from_timestamp is not None:
52
+ params["from_timestamp"] = from_timestamp.isoformat() # may contain + sign
53
+ if to_timestamp is not None:
54
+ params["to_timestamp"] = to_timestamp.isoformat() # may contain + sign
55
+ url = f"{DEDICATED_DEPLOYMENT_URL}/usage_workspace?{urllib.parse.urlencode(params)}"
56
+ response = requests.get(url)
57
+ if response.status_code != 200:
58
+ return response.status_code, response.text
59
+ return response.status_code, response.json()
60
+
61
+
62
+ def get_deployment_usage(api_key, deployment_name, from_timestamp, to_timestamp):
63
+ params = {"api_key": api_key, "deployment_name": deployment_name}
64
+ if from_timestamp is not None:
65
+ params["from_timestamp"] = from_timestamp.isoformat() # may contain + sign
66
+ if to_timestamp is not None:
67
+ params["to_timestamp"] = to_timestamp.isoformat() # may contain + sign
68
+ url = f"{DEDICATED_DEPLOYMENT_URL}/usage_deployment?{urllib.parse.urlencode(params)}"
69
+ response = requests.get(url)
70
+ if response.status_code != 200:
71
+ return response.status_code, response.text
72
+ return response.status_code, response.json()
73
+
74
+
75
+ def pause_deployment(api_key, deployment_name):
76
+ url = f"{DEDICATED_DEPLOYMENT_URL}/pause"
77
+ response = requests.post(url, json={"api_key": api_key, "deployment_name": deployment_name})
78
+ if response.status_code != 200:
79
+ return response.status_code, response.text
80
+ return response.status_code, response.json()
81
+
82
+
83
+ def resume_deployment(api_key, deployment_name):
84
+ url = f"{DEDICATED_DEPLOYMENT_URL}/resume"
85
+ response = requests.post(url, json={"api_key": api_key, "deployment_name": deployment_name})
86
+ if response.status_code != 200:
87
+ return response.status_code, response.text
88
+ return response.status_code, response.json()
89
+
90
+
91
+ def delete_deployment(api_key, deployment_name):
92
+ url = f"{DEDICATED_DEPLOYMENT_URL}/delete"
93
+ response = requests.post(url, json={"api_key": api_key, "deployment_name": deployment_name})
94
+ if response.status_code != 200:
95
+ return response.status_code, response.text
96
+ return response.status_code, response.json()
97
+
98
+
99
+ def list_machine_types(api_key):
100
+ url = f"{DEDICATED_DEPLOYMENT_URL}/machine_types?api_key={api_key}"
101
+ response = requests.get(url)
102
+ if response.status_code != 200:
103
+ return response.status_code, response.text
104
+ return response.status_code, response.json()
105
+
106
+
107
+ def get_deployment_log(api_key, deployment_name, from_timestamp=None, to_timestamp=None, max_entries=-1):
108
+ params = {"api_key": api_key, "deployment_name": deployment_name}
109
+ if from_timestamp is not None:
110
+ params["from_timestamp"] = from_timestamp.isoformat() # may contain + sign
111
+ if to_timestamp is not None:
112
+ params["to_timestamp"] = to_timestamp.isoformat() # may contain + sign
113
+ if max_entries > 0:
114
+ params["max_entries"] = max_entries
115
+ url = f"{DEDICATED_DEPLOYMENT_URL}/get_log?{urllib.parse.urlencode(params)}"
116
+ response = requests.get(url)
117
+ if response.status_code != 200:
118
+ return response.status_code, response.text
119
+ return response.status_code, response.json()