unitlab 2.0.5__tar.gz → 2.0.6__tar.gz
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.
- {unitlab-2.0.5/src/unitlab.egg-info → unitlab-2.0.6}/PKG-INFO +1 -1
- {unitlab-2.0.5 → unitlab-2.0.6}/setup.py +1 -1
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab/client.py +44 -43
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab/dataset.py +23 -19
- {unitlab-2.0.5 → unitlab-2.0.6/src/unitlab.egg-info}/PKG-INFO +1 -1
- {unitlab-2.0.5 → unitlab-2.0.6}/LICENSE.md +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/README.md +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/setup.cfg +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab/__init__.py +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab/__main__.py +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab/exceptions.py +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab/main.py +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab.egg-info/SOURCES.txt +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab.egg-info/dependency_links.txt +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab.egg-info/entry_points.txt +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab.egg-info/requires.txt +0 -0
- {unitlab-2.0.5 → unitlab-2.0.6}/src/unitlab.egg-info/top_level.txt +0 -0
@@ -74,7 +74,7 @@ class UnitlabClient:
|
|
74
74
|
)
|
75
75
|
logger.info("Found a Unitlab API key in your environment.")
|
76
76
|
if api_url is None:
|
77
|
-
|
77
|
+
api_url = os.environ.get("UNITLAB_BASE_URL", "https://api.unitlab.ai")
|
78
78
|
|
79
79
|
self.api_key = api_key
|
80
80
|
self.api_url = api_url
|
@@ -144,53 +144,54 @@ class UnitlabClient:
|
|
144
144
|
if not os.path.isdir(directory):
|
145
145
|
raise ValueError(f"Directory {directory} does not exist")
|
146
146
|
|
147
|
+
files = [
|
148
|
+
file
|
149
|
+
for files_list in (
|
150
|
+
glob.glob(os.path.join(directory, "") + extension)
|
151
|
+
for extension in ["*jpg", "*png", "*jpeg", "*webp"]
|
152
|
+
)
|
153
|
+
for file in files_list
|
154
|
+
]
|
155
|
+
filtered_files = []
|
156
|
+
for file in files:
|
157
|
+
file_size = os.path.getsize(file) / 1024 / 1024
|
158
|
+
if file_size > 6:
|
159
|
+
logger.warning(
|
160
|
+
f"File {file} is too large ({file_size:.4f} megabytes) skipping, max size is 6 MB"
|
161
|
+
)
|
162
|
+
continue
|
163
|
+
filtered_files.append(file)
|
164
|
+
|
165
|
+
num_files = len(filtered_files)
|
166
|
+
num_batches = (num_files + batch_size - 1) // batch_size
|
167
|
+
|
147
168
|
async def post_file(
|
148
169
|
session: aiohttp.ClientSession, file: str, project_id: str, retries=3
|
149
170
|
):
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
url=urllib.parse.urljoin(
|
156
|
-
self.api_url, "/api/sdk/upload-data/"
|
157
|
-
),
|
158
|
-
data=aiohttp.FormData(
|
159
|
-
fields={"project": project_id, "file": f}
|
160
|
-
),
|
161
|
-
)
|
162
|
-
response.raise_for_status()
|
163
|
-
return 1
|
164
|
-
except aiohttp.client_exceptions.ServerDisconnectedError as e:
|
165
|
-
logger.warning(f"Error: {e}: Retrying...")
|
166
|
-
await asyncio.sleep(0.1)
|
167
|
-
continue
|
168
|
-
except Exception as e:
|
169
|
-
logger.error(f"Error uploading file {file} - {e}")
|
170
|
-
return 0
|
171
|
-
|
172
|
-
async def main():
|
173
|
-
files = [
|
174
|
-
file
|
175
|
-
for files_list in (
|
176
|
-
glob.glob(os.path.join(directory, "") + extension)
|
177
|
-
for extension in ["*jpg", "*png", "*jpeg", "*webp"]
|
171
|
+
async with aiofiles.open(file, "rb") as f:
|
172
|
+
form_data = aiohttp.FormData()
|
173
|
+
form_data.add_field("project", project_id)
|
174
|
+
form_data.add_field(
|
175
|
+
"file", await f.read(), filename=os.path.basename(file)
|
178
176
|
)
|
179
|
-
for
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
177
|
+
for _ in range(retries):
|
178
|
+
try:
|
179
|
+
await asyncio.sleep(0.1)
|
180
|
+
async with session.post(
|
181
|
+
urllib.parse.urljoin(self.api_url, "/api/sdk/upload-data/"),
|
182
|
+
data=form_data,
|
183
|
+
) as response:
|
184
|
+
response.raise_for_status()
|
185
|
+
return 1
|
186
|
+
except aiohttp.ServerDisconnectedError as e:
|
187
|
+
logger.warning(f"Server disconnected: {e}, Retrying...")
|
188
|
+
await asyncio.sleep(0.1)
|
189
|
+
continue
|
190
|
+
except Exception as e:
|
191
|
+
logger.error(f"Error uploading file {file} - {e}")
|
192
|
+
return 0
|
193
193
|
|
194
|
+
async def main():
|
194
195
|
logger.info(f"Uploading {num_files} files to project {project_id}")
|
195
196
|
with tqdm.tqdm(total=num_files, ncols=80) as pbar:
|
196
197
|
async with aiohttp.ClientSession(
|
@@ -131,7 +131,7 @@ class COCO:
|
|
131
131
|
if ann["area"] > areaRng[0] and ann["area"] < areaRng[1]
|
132
132
|
]
|
133
133
|
)
|
134
|
-
if
|
134
|
+
if iscrowd:
|
135
135
|
ids = [ann["id"] for ann in anns if ann["iscrowd"] == iscrowd]
|
136
136
|
else:
|
137
137
|
ids = [ann["id"] for ann in anns]
|
@@ -200,7 +200,7 @@ class COCO:
|
|
200
200
|
"""
|
201
201
|
if self._is_array_like(ids):
|
202
202
|
return [self.anns[id] for id in ids]
|
203
|
-
elif
|
203
|
+
elif isinstance(ids, int):
|
204
204
|
return [self.anns[ids]]
|
205
205
|
|
206
206
|
def loadCats(self, ids=[]):
|
@@ -211,7 +211,7 @@ class COCO:
|
|
211
211
|
"""
|
212
212
|
if self._is_array_like(ids):
|
213
213
|
return [self.cats[id] for id in ids]
|
214
|
-
elif
|
214
|
+
elif isinstance(ids, int):
|
215
215
|
return [self.cats[ids]]
|
216
216
|
|
217
217
|
def loadImgs(self, ids=[]):
|
@@ -222,7 +222,7 @@ class COCO:
|
|
222
222
|
"""
|
223
223
|
if self._is_array_like(ids):
|
224
224
|
return [self.imgs[id] for id in ids]
|
225
|
-
elif
|
225
|
+
elif isinstance(ids, int):
|
226
226
|
return [self.imgs[ids]]
|
227
227
|
|
228
228
|
|
@@ -279,23 +279,27 @@ class DatasetUploadHandler(COCO):
|
|
279
279
|
return
|
280
280
|
return getattr(self, f"get_{self.annotation_type}_payload")(anns)
|
281
281
|
|
282
|
-
async def upload_image(self, session, url, image_id):
|
282
|
+
async def upload_image(self, session, url, image_id, retries=3):
|
283
283
|
image = self.loadImgs(image_id)[0]
|
284
284
|
file_name = image["file_name"]
|
285
285
|
payload = self.get_payload(image_id)
|
286
286
|
if payload:
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
287
|
+
async with aiofiles.open(
|
288
|
+
os.path.join(self.data_path, file_name), "rb"
|
289
|
+
) as f:
|
290
|
+
form_data = aiohttp.FormData()
|
291
|
+
form_data.add_field("file", await f.read(), filename=file_name)
|
292
|
+
form_data.add_field("result", self.get_payload(image_id))
|
293
|
+
for _ in range(retries):
|
294
|
+
try:
|
295
|
+
await asyncio.sleep(0.1)
|
296
|
+
async with session.post(url, data=form_data) as response:
|
297
|
+
response.raise_for_status()
|
298
|
+
return 1
|
299
|
+
except aiohttp.ServerDisconnectedError as e:
|
300
|
+
logger.warning(f"Server disconnected - {e}, retrying...")
|
301
|
+
await asyncio.sleep(0.1)
|
302
|
+
continue
|
303
|
+
except Exception as e:
|
304
|
+
logger.error(f"Error uploading file {file_name} - {e}")
|
301
305
|
return 0
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|