Skip to content

Commit a61e64d

Browse files
committed
add archive, batch.project, changelog
1 parent 658c618 commit a61e64d

File tree

5 files changed

+98
-16
lines changed

5 files changed

+98
-16
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
# Version 3.20.0 (2022-04-27)
4+
## Added
5+
* Batches in a project can be retrieved with `project.batches()`
6+
* Added `Batch.remove_queued_data_rows()` to cancel remaining data rows in batch
7+
* Added `Batch.export_data_rows()` which returns `DataRow`s for a batch
8+
9+
## Fix
10+
* `batch.project()` now works
11+
312
# Version 3.19.1 (2022-04-14)
413
## Fix
514
* `create_data_rows` and `create_data_rows_sync` now uploads the file with a mimetype

labelbox/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name = "labelbox"
2-
__version__ = "3.19.1"
2+
__version__ = "3.20.0"
33

44
import sys
55
import warnings

labelbox/schema/batch.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from typing import Generator
22
from labelbox.orm.db_object import DbObject, experimental
3+
from labelbox.orm import query
34
from labelbox.orm.model import Entity, Field, Relationship
4-
from labelbox.exceptions import LabelboxError
5+
from labelbox.exceptions import LabelboxError, ResourceNotFoundError
56
from io import StringIO
67
import ndjson
78
import requests
@@ -30,9 +31,49 @@ class Batch(DbObject):
3031
size = Field.Int("size")
3132

3233
# Relationships
33-
project = Relationship.ToOne("Project")
3434
created_by = Relationship.ToOne("User")
3535

36+
def __init__(self, client, project_id, *args, **kwargs):
37+
super().__init__(client, *args, **kwargs)
38+
self.project_id = project_id
39+
40+
def project(self) -> Entity.Project:
41+
""" Returns Project which this Batch belongs to
42+
43+
Raises:
44+
LabelboxError: if the project is not found
45+
"""
46+
query_str = """query getProjectPyApi($projectId: ID!) {
47+
project(
48+
where: {id: $projectId}){
49+
%s
50+
}}""" % query.results_query_part(Entity.Project)
51+
params = {"projectId": self.project_id}
52+
response = self.client.execute(query_str, params)
53+
54+
if response is None:
55+
raise ResourceNotFoundError(Entity.Project, params)
56+
57+
return Entity.Project(self.client, response["project"])
58+
59+
def remove_queued_data_rows(self) -> None:
60+
""" Removes remaining queued data rows from the batch and labeling queue.
61+
62+
Args:
63+
batch (Batch): Batch to remove queued data rows from
64+
"""
65+
66+
project_id_param = "projectId"
67+
batch_id_param = "batchId"
68+
self.client.execute("""mutation ArchiveBatchPyApi($%s: ID!, $%s: ID!) {
69+
project(where: {id: $%s}) { archiveBatch(batchId: $%s) { id archivedAt } }
70+
}""" % (project_id_param, batch_id_param, project_id_param,
71+
batch_id_param), {
72+
project_id_param: self.project_id,
73+
batch_id_param: self.uid
74+
},
75+
experimental=True)
76+
3677
def export_data_rows(self, timeout_seconds=120) -> Generator:
3778
""" Returns a generator that produces all data rows that are currently
3879
in this batch.

labelbox/schema/project.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ def create_batch(self, name: str, data_rows: List[str], priority: int = 5):
609609
experimental=True)["project"][method]
610610

611611
res['size'] = len(dr_ids)
612-
return Entity.Batch(self.client, res)
612+
return Entity.Batch(self.client, self.uid, res)
613613

614614
def _update_queue_mode(self,
615615
mode: "Project.QueueMode") -> "Project.QueueMode":
@@ -851,17 +851,17 @@ def batches(self) -> PaginatedCollection:
851851
project(where: {id: $%s}) {id
852852
batches(after: $from, first: $first) { nodes { %s } pageInfo { endCursor }}}}
853853
""" % (id_param, id_param, query.results_query_part(Entity.Batch))
854-
return PaginatedCollection(self.client,
855-
query_str, {id_param: self.uid},
856-
['project', 'batches', 'nodes'],
857-
Entity.Batch,
858-
cursor_path={
859-
'project': None,
860-
'batches': None,
861-
'pageInfo': None,
862-
'endCursor': None
863-
},
864-
experimental=True)
854+
return PaginatedCollection(
855+
self.client,
856+
query_str, {id_param: self.uid}, ['project', 'batches', 'nodes'],
857+
lambda client, res: Entity.Batch(client, self.uid, res),
858+
cursor_path={
859+
'project': None,
860+
'batches': None,
861+
'pageInfo': None,
862+
'endCursor': None
863+
},
864+
experimental=True)
865865

866866
def upload_annotations(
867867
self,

tests/integration/test_batch.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ def big_dataset(dataset: Dataset):
1818
yield dataset
1919

2020

21+
@pytest.fixture
22+
def small_dataset(dataset: Dataset):
23+
task = dataset.create_data_rows([
24+
{
25+
"row_data": IMAGE_URL,
26+
"external_id": "my-image"
27+
},
28+
] * 3)
29+
task.wait_till_done()
30+
31+
yield dataset
32+
33+
2134
def test_create_batch(configured_project: Project, big_dataset: Dataset):
2235
configured_project.update(queue_mode=Project.QueueMode.Batch)
2336

@@ -37,11 +50,30 @@ def test_export_data_rows(configured_project: Project, dataset: Dataset):
3750
] * n_data_rows)
3851
task.wait_till_done()
3952

40-
data_rows = [dr.uid for dr in list(big_dataset.export_data_rows())]
53+
data_rows = [dr.uid for dr in list(dataset.export_data_rows())]
4154
batch = configured_project.create_batch("batch test", data_rows)
4255

4356
result = list(batch.export_data_rows())
4457
exported_data_rows = [dr.uid for dr in result]
4558

4659
assert len(result) == n_data_rows
4760
assert set(data_rows) == set(exported_data_rows)
61+
62+
63+
def test_archive_batch(configured_project: Project, small_dataset: Dataset):
64+
data_rows = [dr.uid for dr in list(small_dataset.export_data_rows())]
65+
batch = configured_project.create_batch("batch to archive", data_rows)
66+
batch.remove_queued_data_rows()
67+
exported_data_rows = list(batch.export_data_rows())
68+
69+
assert len(exported_data_rows) == 0
70+
71+
72+
def test_batch_project(configured_project: Project, small_dataset: Dataset):
73+
data_rows = [dr.uid for dr in list(small_dataset.export_data_rows())]
74+
batch = configured_project.create_batch(
75+
"batch to test project relationship", data_rows)
76+
project_from_batch = batch.project()
77+
78+
assert project_from_batch.uid == configured_project.uid
79+
assert project_from_batch.name == configured_project.name

0 commit comments

Comments
 (0)