arkindex-base-worker 0.4.0b2__tar.gz → 0.4.0b3__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.
Files changed (56) hide show
  1. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/PKG-INFO +1 -1
  2. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_base_worker.egg-info/PKG-INFO +1 -1
  3. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/utils.py +6 -1
  4. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/element.py +47 -0
  5. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/pyproject.toml +1 -1
  6. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_elements.py +133 -0
  7. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/LICENSE +0 -0
  8. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/README.md +0 -0
  9. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_base_worker.egg-info/SOURCES.txt +0 -0
  10. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_base_worker.egg-info/dependency_links.txt +0 -0
  11. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_base_worker.egg-info/requires.txt +0 -0
  12. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_base_worker.egg-info/top_level.txt +0 -0
  13. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/__init__.py +0 -0
  14. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/cache.py +0 -0
  15. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/image.py +0 -0
  16. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/models.py +0 -0
  17. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/__init__.py +0 -0
  18. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/base.py +0 -0
  19. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/classification.py +0 -0
  20. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/corpus.py +0 -0
  21. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/dataset.py +0 -0
  22. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/entity.py +0 -0
  23. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/image.py +0 -0
  24. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/metadata.py +0 -0
  25. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/task.py +0 -0
  26. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/training.py +0 -0
  27. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/transcription.py +0 -0
  28. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/arkindex_worker/worker/version.py +0 -0
  29. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/hooks/pre_gen_project.py +0 -0
  30. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/setup.cfg +0 -0
  31. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/__init__.py +0 -0
  32. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/conftest.py +0 -0
  33. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_base_worker.py +0 -0
  34. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_cache.py +0 -0
  35. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_dataset_worker.py +0 -0
  36. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_element.py +0 -0
  37. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/__init__.py +0 -0
  38. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_classifications.py +0 -0
  39. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_cli.py +0 -0
  40. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_corpus.py +0 -0
  41. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_dataset.py +0 -0
  42. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_entities.py +0 -0
  43. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_image.py +0 -0
  44. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_metadata.py +0 -0
  45. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_task.py +0 -0
  46. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_training.py +0 -0
  47. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_transcriptions.py +0 -0
  48. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_elements_worker/test_worker.py +0 -0
  49. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_image.py +0 -0
  50. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_merge.py +0 -0
  51. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/tests/test_utils.py +0 -0
  52. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/worker-demo/tests/__init__.py +0 -0
  53. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/worker-demo/tests/conftest.py +0 -0
  54. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/worker-demo/tests/test_worker.py +0 -0
  55. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/worker-demo/worker_demo/__init__.py +0 -0
  56. {arkindex_base_worker-0.4.0b2 → arkindex_base_worker-0.4.0b3}/worker-demo/worker_demo/worker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arkindex-base-worker
3
- Version: 0.4.0b2
3
+ Version: 0.4.0b3
4
4
  Summary: Base Worker to easily build Arkindex ML workflows
5
5
  Author-email: Teklia <contact@teklia.com>
6
6
  Maintainer-email: Teklia <contact@teklia.com>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arkindex-base-worker
3
- Version: 0.4.0b2
3
+ Version: 0.4.0b3
4
4
  Summary: Base Worker to easily build Arkindex ML workflows
5
5
  Author-email: Teklia <contact@teklia.com>
6
6
  Maintainer-email: Teklia <contact@teklia.com>
@@ -24,7 +24,12 @@ def pluralize(singular: str, count: int) -> str:
24
24
  if count == 1:
25
25
  return singular
26
26
 
27
- some_exceptions = {"entity": "entities", "metadata": "metadata", "class": "classes"}
27
+ some_exceptions = {
28
+ "child": "children",
29
+ "class": "classes",
30
+ "entity": "entities",
31
+ "metadata": "metadata",
32
+ }
28
33
  if singular in some_exceptions:
29
34
  return some_exceptions[singular]
30
35
 
@@ -3,6 +3,7 @@ ElementsWorker methods for elements and element types.
3
3
  """
4
4
 
5
5
  from collections.abc import Iterable
6
+ from operator import attrgetter
6
7
  from typing import NamedTuple
7
8
  from uuid import UUID
8
9
  from warnings import warn
@@ -346,6 +347,52 @@ class ElementMixin:
346
347
  child=child.id,
347
348
  )
348
349
 
350
+ @unsupported_cache
351
+ @batch_publication
352
+ def create_element_children(
353
+ self,
354
+ parent: Element,
355
+ children: list[Element],
356
+ batch_size: int = DEFAULT_BATCH_SIZE,
357
+ ) -> list[str]:
358
+ """
359
+ Link multiple elements to a single parent through the API.
360
+
361
+ :param parent: Parent element.
362
+ :param children: A list of child elements.
363
+ :param batch_size: The size of each batch, which will be used to split the publication to avoid API errors.
364
+
365
+ :returns: A list containing the string UUID of each child linked to the parent.
366
+ """
367
+ assert parent and isinstance(
368
+ parent, Element
369
+ ), "parent shouldn't be null and should be of type Element"
370
+
371
+ assert children and isinstance(
372
+ children, list
373
+ ), "children shouldn't be null and should be of type list"
374
+
375
+ for index, child in enumerate(children):
376
+ assert isinstance(
377
+ child, Element
378
+ ), f"Child at index {index} in children: Should be of type Element"
379
+
380
+ if self.is_read_only:
381
+ logger.warning("Cannot link elements as this worker is in read-only mode")
382
+ return
383
+
384
+ return [
385
+ child_id
386
+ for batch in make_batches(children, "child", batch_size)
387
+ for child_id in self.api_client.request(
388
+ "CreateElementChildren",
389
+ id=parent.id,
390
+ body={
391
+ "children": list(map(attrgetter("id"), batch)),
392
+ },
393
+ )["children"]
394
+ ]
395
+
349
396
  def partial_update_element(
350
397
  self, element: Element | CachedElement, **kwargs
351
398
  ) -> dict:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "arkindex-base-worker"
7
- version = "0.4.0b2"
7
+ version = "0.4.0b3"
8
8
  description = "Base Worker to easily build Arkindex ML workflows"
9
9
  license = { file = "LICENSE" }
10
10
  dependencies = [
@@ -1500,6 +1500,139 @@ def test_create_element_parent(responses, mock_elements_worker):
1500
1500
  }
1501
1501
 
1502
1502
 
1503
+ @pytest.mark.parametrize(
1504
+ ("arg_name", "data", "error_message"),
1505
+ [
1506
+ (
1507
+ "parent",
1508
+ None,
1509
+ "parent shouldn't be null and should be of type Element",
1510
+ ),
1511
+ (
1512
+ "parent",
1513
+ "not element type",
1514
+ "parent shouldn't be null and should be of type Element",
1515
+ ),
1516
+ (
1517
+ "children",
1518
+ None,
1519
+ "children shouldn't be null and should be of type list",
1520
+ ),
1521
+ (
1522
+ "children",
1523
+ "not a list",
1524
+ "children shouldn't be null and should be of type list",
1525
+ ),
1526
+ (
1527
+ "children",
1528
+ [
1529
+ Element({"id": "11111111-1111-1111-1111-111111111111"}),
1530
+ "not element type",
1531
+ ],
1532
+ "Child at index 1 in children: Should be of type Element",
1533
+ ),
1534
+ ],
1535
+ )
1536
+ def test_create_element_children_wrong_params(
1537
+ arg_name, data, error_message, mock_elements_worker
1538
+ ):
1539
+ with pytest.raises(AssertionError, match=error_message):
1540
+ mock_elements_worker.create_element_children(
1541
+ **{
1542
+ "parent": Element({"id": "12341234-1234-1234-1234-123412341234"}),
1543
+ "children": [
1544
+ Element({"id": "11111111-1111-1111-1111-111111111111"}),
1545
+ Element({"id": "22222222-2222-2222-2222-222222222222"}),
1546
+ ],
1547
+ # Overwrite with wrong data
1548
+ arg_name: data,
1549
+ },
1550
+ )
1551
+
1552
+
1553
+ def test_create_element_children_api_error(responses, mock_elements_worker):
1554
+ parent = Element({"id": "12341234-1234-1234-1234-123412341234"})
1555
+ responses.add(
1556
+ responses.POST,
1557
+ f"http://testserver/api/v1/element/parent/{parent.id}/",
1558
+ status=418,
1559
+ )
1560
+
1561
+ with pytest.raises(ErrorResponse):
1562
+ mock_elements_worker.create_element_children(
1563
+ parent=parent,
1564
+ children=[
1565
+ Element({"id": "11111111-1111-1111-1111-111111111111"}),
1566
+ Element({"id": "22222222-2222-2222-2222-222222222222"}),
1567
+ ],
1568
+ )
1569
+
1570
+ assert len(responses.calls) == len(BASE_API_CALLS) + 1
1571
+ assert [
1572
+ (call.request.method, call.request.url) for call in responses.calls
1573
+ ] == BASE_API_CALLS + [
1574
+ (
1575
+ "POST",
1576
+ f"http://testserver/api/v1/element/parent/{parent.id}/",
1577
+ )
1578
+ ]
1579
+
1580
+
1581
+ @pytest.mark.parametrize("batch_size", [DEFAULT_BATCH_SIZE, 1])
1582
+ def test_create_element_children(batch_size, responses, mock_elements_worker):
1583
+ parent = Element({"id": "12341234-1234-1234-1234-123412341234"})
1584
+
1585
+ first_child = Element({"id": "11111111-1111-1111-1111-111111111111"})
1586
+ second_child = Element({"id": "22222222-2222-2222-2222-222222222222"})
1587
+
1588
+ responses.add(
1589
+ responses.POST,
1590
+ f"http://testserver/api/v1/element/parent/{parent.id}/",
1591
+ status=200,
1592
+ json={"children": []},
1593
+ )
1594
+
1595
+ mock_elements_worker.create_element_children(
1596
+ parent=parent,
1597
+ children=[first_child, second_child],
1598
+ batch_size=batch_size,
1599
+ )
1600
+
1601
+ bulk_api_calls = [
1602
+ (
1603
+ "POST",
1604
+ f"http://testserver/api/v1/element/parent/{parent.id}/",
1605
+ )
1606
+ ]
1607
+ if batch_size != DEFAULT_BATCH_SIZE:
1608
+ bulk_api_calls.append(
1609
+ (
1610
+ "POST",
1611
+ f"http://testserver/api/v1/element/parent/{parent.id}/",
1612
+ )
1613
+ )
1614
+
1615
+ assert len(responses.calls) == len(BASE_API_CALLS) + len(bulk_api_calls)
1616
+ assert [
1617
+ (call.request.method, call.request.url) for call in responses.calls
1618
+ ] == BASE_API_CALLS + bulk_api_calls
1619
+
1620
+ bodies = []
1621
+ first_call_idx = None
1622
+ if batch_size > 1:
1623
+ first_call_idx = -1
1624
+ bodies.append({"children": [first_child.id, second_child.id]})
1625
+ else:
1626
+ first_call_idx = -2
1627
+ bodies.append({"children": [first_child.id]})
1628
+ bodies.append({"children": [second_child.id]})
1629
+
1630
+ assert [
1631
+ json.loads(bulk_call.request.body)
1632
+ for bulk_call in responses.calls[first_call_idx:]
1633
+ ] == bodies
1634
+
1635
+
1503
1636
  @pytest.mark.parametrize(
1504
1637
  ("payload", "error"),
1505
1638
  [