arkindex-base-worker 0.3.7rc10__py3-none-any.whl → 0.4.0__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 (54) hide show
  1. {arkindex_base_worker-0.3.7rc10.dist-info → arkindex_base_worker-0.4.0.dist-info}/METADATA +16 -20
  2. arkindex_base_worker-0.4.0.dist-info/RECORD +61 -0
  3. {arkindex_base_worker-0.3.7rc10.dist-info → arkindex_base_worker-0.4.0.dist-info}/WHEEL +1 -1
  4. arkindex_worker/cache.py +1 -1
  5. arkindex_worker/image.py +120 -1
  6. arkindex_worker/models.py +6 -0
  7. arkindex_worker/utils.py +85 -4
  8. arkindex_worker/worker/__init__.py +68 -162
  9. arkindex_worker/worker/base.py +39 -34
  10. arkindex_worker/worker/classification.py +34 -18
  11. arkindex_worker/worker/corpus.py +86 -0
  12. arkindex_worker/worker/dataset.py +71 -1
  13. arkindex_worker/worker/element.py +352 -91
  14. arkindex_worker/worker/entity.py +11 -11
  15. arkindex_worker/worker/image.py +21 -0
  16. arkindex_worker/worker/metadata.py +19 -9
  17. arkindex_worker/worker/process.py +92 -0
  18. arkindex_worker/worker/task.py +5 -4
  19. arkindex_worker/worker/training.py +25 -10
  20. arkindex_worker/worker/transcription.py +89 -68
  21. arkindex_worker/worker/version.py +3 -1
  22. tests/__init__.py +8 -0
  23. tests/conftest.py +36 -52
  24. tests/test_base_worker.py +212 -12
  25. tests/test_dataset_worker.py +21 -45
  26. tests/test_elements_worker/{test_classifications.py → test_classification.py} +216 -100
  27. tests/test_elements_worker/test_cli.py +3 -11
  28. tests/test_elements_worker/test_corpus.py +168 -0
  29. tests/test_elements_worker/test_dataset.py +7 -12
  30. tests/test_elements_worker/test_element.py +427 -0
  31. tests/test_elements_worker/test_element_create_multiple.py +715 -0
  32. tests/test_elements_worker/test_element_create_single.py +528 -0
  33. tests/test_elements_worker/test_element_list_children.py +969 -0
  34. tests/test_elements_worker/test_element_list_parents.py +530 -0
  35. tests/test_elements_worker/{test_entities.py → test_entity_create.py} +37 -195
  36. tests/test_elements_worker/test_entity_list_and_check.py +160 -0
  37. tests/test_elements_worker/test_image.py +66 -0
  38. tests/test_elements_worker/test_metadata.py +230 -139
  39. tests/test_elements_worker/test_process.py +89 -0
  40. tests/test_elements_worker/test_task.py +8 -18
  41. tests/test_elements_worker/test_training.py +17 -8
  42. tests/test_elements_worker/test_transcription_create.py +873 -0
  43. tests/test_elements_worker/test_transcription_create_with_elements.py +951 -0
  44. tests/test_elements_worker/test_transcription_list.py +450 -0
  45. tests/test_elements_worker/test_version.py +60 -0
  46. tests/test_elements_worker/test_worker.py +563 -279
  47. tests/test_image.py +432 -209
  48. tests/test_merge.py +1 -2
  49. tests/test_utils.py +66 -3
  50. arkindex_base_worker-0.3.7rc10.dist-info/RECORD +0 -47
  51. tests/test_elements_worker/test_elements.py +0 -2713
  52. tests/test_elements_worker/test_transcriptions.py +0 -2119
  53. {arkindex_base_worker-0.3.7rc10.dist-info → arkindex_base_worker-0.4.0.dist-info}/LICENSE +0 -0
  54. {arkindex_base_worker-0.3.7rc10.dist-info → arkindex_base_worker-0.4.0.dist-info}/top_level.txt +0 -0
tests/conftest.py CHANGED
@@ -23,14 +23,15 @@ from arkindex_worker.cache import (
23
23
  init_cache_db,
24
24
  )
25
25
  from arkindex_worker.models import Artifact, Dataset, Set
26
- from arkindex_worker.worker import BaseWorker, DatasetWorker, ElementsWorker
26
+ from arkindex_worker.worker import (
27
+ BaseWorker,
28
+ DatasetWorker,
29
+ ElementsWorker,
30
+ ProcessMode,
31
+ )
27
32
  from arkindex_worker.worker.dataset import DatasetState
28
33
  from arkindex_worker.worker.transcription import TextOrientation
29
-
30
- FIXTURES_DIR = Path(__file__).resolve().parent / "data"
31
- SAMPLES_DIR = Path(__file__).resolve().parent / "samples"
32
-
33
- PROCESS_ID = "cafecafe-cafe-cafe-cafe-cafecafecafe"
34
+ from tests import CORPUS_ID, SAMPLES_DIR
34
35
 
35
36
  __yaml_cache = {}
36
37
 
@@ -45,7 +46,7 @@ def _disable_sleep(monkeypatch):
45
46
  monkeypatch.setattr(time, "sleep", lambda x: None)
46
47
 
47
48
 
48
- @pytest.fixture()
49
+ @pytest.fixture
49
50
  def _cache_yaml(monkeypatch):
50
51
  """
51
52
  Cache all calls to yaml.safe_load in order to speedup
@@ -93,7 +94,7 @@ def _setup_api(responses, monkeypatch, _cache_yaml):
93
94
 
94
95
  # Fallback to prod environment
95
96
  if schema_url is None:
96
- schema_url = "https://arkindex.teklia.com/api/v1/openapi/?format=openapi-json"
97
+ schema_url = "https://arkindex.teklia.com/api/v1/openapi/?format=json"
97
98
  monkeypatch.setenv("ARKINDEX_API_SCHEMA_URL", schema_url)
98
99
 
99
100
  # Allow accessing remote API schemas
@@ -110,7 +111,7 @@ def _give_env_variable(monkeypatch):
110
111
  monkeypatch.setenv("ARKINDEX_WORKER_RUN_ID", "56785678-5678-5678-5678-567856785678")
111
112
 
112
113
 
113
- @pytest.fixture()
114
+ @pytest.fixture
114
115
  def _mock_worker_run_api(responses):
115
116
  """Provide a mock API response to get worker run information"""
116
117
  payload = {
@@ -159,7 +160,7 @@ def _mock_worker_run_api(responses):
159
160
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
160
161
  "state": "running",
161
162
  "mode": "workers",
162
- "corpus": "11111111-1111-1111-1111-111111111111",
163
+ "corpus": CORPUS_ID,
163
164
  "use_cache": False,
164
165
  "activity_state": "ready",
165
166
  "model_id": None,
@@ -179,7 +180,7 @@ def _mock_worker_run_api(responses):
179
180
  )
180
181
 
181
182
 
182
- @pytest.fixture()
183
+ @pytest.fixture
183
184
  def _mock_worker_run_no_revision_api(responses):
184
185
  """Provide a mock API response to get worker run not linked to a revision information"""
185
186
  payload = {
@@ -226,7 +227,7 @@ def _mock_worker_run_no_revision_api(responses):
226
227
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
227
228
  "state": "running",
228
229
  "mode": "workers",
229
- "corpus": "11111111-1111-1111-1111-111111111111",
230
+ "corpus": CORPUS_ID,
230
231
  "use_cache": False,
231
232
  "activity_state": "ready",
232
233
  "model_id": None,
@@ -246,7 +247,7 @@ def _mock_worker_run_no_revision_api(responses):
246
247
  )
247
248
 
248
249
 
249
- @pytest.fixture()
250
+ @pytest.fixture
250
251
  def _mock_activity_calls(responses):
251
252
  """
252
253
  Mock responses when updating the activity state for multiple element of the same version
@@ -258,7 +259,7 @@ def _mock_activity_calls(responses):
258
259
  )
259
260
 
260
261
 
261
- @pytest.fixture()
262
+ @pytest.fixture
262
263
  def mock_elements_worker(monkeypatch, _mock_worker_run_api):
263
264
  """Build and configure an ElementsWorker with fixed CLI parameters to avoid issues with pytest"""
264
265
  monkeypatch.setattr(sys, "argv", ["worker"])
@@ -267,7 +268,7 @@ def mock_elements_worker(monkeypatch, _mock_worker_run_api):
267
268
  return worker
268
269
 
269
270
 
270
- @pytest.fixture()
271
+ @pytest.fixture
271
272
  def mock_elements_worker_read_only(monkeypatch):
272
273
  """Build and configure an ElementsWorker with fixed CLI parameters to avoid issues with pytest"""
273
274
  monkeypatch.setattr(sys, "argv", ["worker", "--dev"])
@@ -276,14 +277,12 @@ def mock_elements_worker_read_only(monkeypatch):
276
277
  return worker
277
278
 
278
279
 
279
- @pytest.fixture()
280
+ @pytest.fixture
280
281
  def mock_elements_worker_with_list(monkeypatch, responses, mock_elements_worker):
281
282
  """
282
283
  Mock a worker instance to list and retrieve a single element
283
284
  """
284
- monkeypatch.setattr(
285
- mock_elements_worker, "list_elements", lambda: ["1234-deadbeef"]
286
- )
285
+ monkeypatch.setattr(mock_elements_worker, "get_elements", lambda: ["1234-deadbeef"])
287
286
  responses.add(
288
287
  responses.GET,
289
288
  "http://testserver/api/v1/element/1234-deadbeef/",
@@ -297,7 +296,7 @@ def mock_elements_worker_with_list(monkeypatch, responses, mock_elements_worker)
297
296
  return mock_elements_worker
298
297
 
299
298
 
300
- @pytest.fixture()
299
+ @pytest.fixture
301
300
  def mock_cache_db(tmp_path):
302
301
  cache_path = tmp_path / "db.sqlite"
303
302
 
@@ -308,7 +307,7 @@ def mock_cache_db(tmp_path):
308
307
  return cache_path
309
308
 
310
309
 
311
- @pytest.fixture()
310
+ @pytest.fixture
312
311
  def mock_base_worker_with_cache(monkeypatch, _mock_worker_run_api):
313
312
  """Build a BaseWorker using SQLite cache, also mocking a PONOS_TASK"""
314
313
  monkeypatch.setattr(sys, "argv", ["worker"])
@@ -319,7 +318,7 @@ def mock_base_worker_with_cache(monkeypatch, _mock_worker_run_api):
319
318
  return worker
320
319
 
321
320
 
322
- @pytest.fixture()
321
+ @pytest.fixture
323
322
  def mock_elements_worker_with_cache(monkeypatch, mock_cache_db, _mock_worker_run_api):
324
323
  """Build and configure an ElementsWorker using SQLite cache with fixed CLI parameters to avoid issues with pytest"""
325
324
  monkeypatch.setattr(sys, "argv", ["worker", "-d", str(mock_cache_db)])
@@ -330,34 +329,17 @@ def mock_elements_worker_with_cache(monkeypatch, mock_cache_db, _mock_worker_run
330
329
  return worker
331
330
 
332
331
 
333
- @pytest.fixture()
334
- def fake_page_element():
335
- return json.loads((FIXTURES_DIR / "page_element.json").read_text())
336
-
337
-
338
- @pytest.fixture()
339
- def fake_ufcn_worker_version():
340
- return json.loads(
341
- (FIXTURES_DIR / "ufcn_line_historical_worker_version.json").read_text()
342
- )
343
-
344
-
345
- @pytest.fixture()
346
- def fake_transcriptions_small():
347
- return json.loads((FIXTURES_DIR / "line_transcriptions_small.json").read_text())
348
-
349
-
350
- @pytest.fixture()
332
+ @pytest.fixture
351
333
  def model_file_dir():
352
334
  return SAMPLES_DIR / "model_files"
353
335
 
354
336
 
355
- @pytest.fixture()
337
+ @pytest.fixture
356
338
  def model_file_dir_with_subfolder():
357
339
  return SAMPLES_DIR / "root_folder"
358
340
 
359
341
 
360
- @pytest.fixture()
342
+ @pytest.fixture
361
343
  def fake_dummy_worker():
362
344
  api_client = MockApiClient()
363
345
  worker = ElementsWorker()
@@ -365,7 +347,7 @@ def fake_dummy_worker():
365
347
  return worker
366
348
 
367
349
 
368
- @pytest.fixture()
350
+ @pytest.fixture
369
351
  def _mock_cached_elements(mock_cache_db):
370
352
  """Insert few elements in local cache"""
371
353
  CachedElement.create(
@@ -410,7 +392,7 @@ def _mock_cached_elements(mock_cache_db):
410
392
  assert CachedElement.select().count() == 5
411
393
 
412
394
 
413
- @pytest.fixture()
395
+ @pytest.fixture
414
396
  def _mock_cached_images(mock_cache_db):
415
397
  """Insert few elements in local cache"""
416
398
  CachedImage.create(
@@ -422,7 +404,7 @@ def _mock_cached_images(mock_cache_db):
422
404
  assert CachedImage.select().count() == 1
423
405
 
424
406
 
425
- @pytest.fixture()
407
+ @pytest.fixture
426
408
  def _mock_cached_transcriptions(mock_cache_db):
427
409
  """Insert few transcriptions in local cache, on a shared element"""
428
410
  CachedElement.create(
@@ -511,7 +493,7 @@ def _mock_cached_transcriptions(mock_cache_db):
511
493
  )
512
494
 
513
495
 
514
- @pytest.fixture()
496
+ @pytest.fixture
515
497
  def mock_databases(tmp_path):
516
498
  """
517
499
  Initialize several temporary databases
@@ -594,7 +576,7 @@ def mock_databases(tmp_path):
594
576
  return out
595
577
 
596
578
 
597
- @pytest.fixture()
579
+ @pytest.fixture
598
580
  def default_dataset():
599
581
  return Dataset(
600
582
  {
@@ -612,26 +594,28 @@ def default_dataset():
612
594
  )
613
595
 
614
596
 
615
- @pytest.fixture()
597
+ @pytest.fixture
616
598
  def default_train_set(default_dataset):
617
599
  return Set(name="train", dataset=default_dataset)
618
600
 
619
601
 
620
- @pytest.fixture()
602
+ @pytest.fixture
621
603
  def mock_dataset_worker(monkeypatch, mocker, _mock_worker_run_api):
622
604
  monkeypatch.setenv("PONOS_TASK", "my_task")
623
605
  mocker.patch.object(sys, "argv", ["worker"])
624
606
 
625
607
  dataset_worker = DatasetWorker()
626
608
  dataset_worker.configure()
627
- dataset_worker.process_information = {"id": PROCESS_ID}
609
+
610
+ # Update process mode
611
+ dataset_worker.process_information["mode"] = ProcessMode.Dataset
628
612
 
629
613
  assert not dataset_worker.is_read_only
630
614
 
631
615
  return dataset_worker
632
616
 
633
617
 
634
- @pytest.fixture()
618
+ @pytest.fixture
635
619
  def mock_dev_dataset_worker(mocker):
636
620
  mocker.patch.object(
637
621
  sys,
@@ -656,7 +640,7 @@ def mock_dev_dataset_worker(mocker):
656
640
  return dataset_worker
657
641
 
658
642
 
659
- @pytest.fixture()
643
+ @pytest.fixture
660
644
  def default_artifact():
661
645
  return Artifact(
662
646
  **{
tests/test_base_worker.py CHANGED
@@ -11,7 +11,7 @@ from arkindex.mock import MockApiClient
11
11
  from arkindex_worker import logger
12
12
  from arkindex_worker.worker import BaseWorker, ElementsWorker
13
13
  from arkindex_worker.worker.base import ExtrasDirNotFoundError
14
- from tests.conftest import FIXTURES_DIR
14
+ from tests import CORPUS_ID, FIXTURES_DIR
15
15
 
16
16
 
17
17
  def test_init_default_local_share():
@@ -178,7 +178,7 @@ def test_configure_worker_run(mocker, responses, caplog):
178
178
  "model_version": None,
179
179
  "process": {
180
180
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
181
- "corpus": "11111111-1111-1111-1111-111111111111",
181
+ "corpus": CORPUS_ID,
182
182
  },
183
183
  "summary": "Worker Fake worker @ 123412",
184
184
  }
@@ -206,6 +206,7 @@ def test_configure_worker_run(mocker, responses, caplog):
206
206
  "Loaded Worker Fake worker @ 123412 from API",
207
207
  ),
208
208
  ("arkindex_worker", logging.INFO, "Loaded user configuration from WorkerRun"),
209
+ ("arkindex_worker", logging.INFO, "User configuration retrieved"),
209
210
  ]
210
211
 
211
212
  assert worker.user_configuration == {"a": "b"}
@@ -270,7 +271,7 @@ def test_configure_user_configuration_defaults(mocker, responses):
270
271
  "model_version": None,
271
272
  "process": {
272
273
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
273
- "corpus": "11111111-1111-1111-1111-111111111111",
274
+ "corpus": CORPUS_ID,
274
275
  },
275
276
  "summary": "Worker Fake worker @ 123412",
276
277
  }
@@ -284,12 +285,21 @@ def test_configure_user_configuration_defaults(mocker, responses):
284
285
 
285
286
  worker.configure()
286
287
 
287
- assert worker.config == {"param_1": "/some/path/file.pth", "param_2": 12}
288
288
  assert worker.user_configuration == {
289
289
  "integer_parameter": 0,
290
290
  "param_3": "Animula vagula blandula",
291
291
  "param_5": True,
292
292
  }
293
+ # All configurations are merged
294
+ assert worker.config == {
295
+ # Default config
296
+ "param_1": "/some/path/file.pth",
297
+ "param_2": 12,
298
+ # User config
299
+ "integer_parameter": 0,
300
+ "param_3": "Animula vagula blandula",
301
+ "param_5": True,
302
+ }
293
303
 
294
304
 
295
305
  @pytest.mark.parametrize("debug", [True, False])
@@ -319,7 +329,7 @@ def test_configure_user_config_debug(mocker, responses, debug):
319
329
  },
320
330
  "process": {
321
331
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
322
- "corpus": "11111111-1111-1111-1111-111111111111",
332
+ "corpus": CORPUS_ID,
323
333
  },
324
334
  "summary": "Worker Fake worker @ 123412",
325
335
  }
@@ -367,7 +377,7 @@ def test_configure_worker_run_missing_conf(mocker, responses):
367
377
  "configuration": {"id": "bbbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "name": "BBB"},
368
378
  "process": {
369
379
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
370
- "corpus": "11111111-1111-1111-1111-111111111111",
380
+ "corpus": CORPUS_ID,
371
381
  },
372
382
  "summary": "Worker Fake worker @ 123412",
373
383
  }
@@ -409,7 +419,7 @@ def test_configure_worker_run_no_worker_run_conf(mocker, responses):
409
419
  "configuration": None,
410
420
  "process": {
411
421
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
412
- "corpus": "11111111-1111-1111-1111-111111111111",
422
+ "corpus": CORPUS_ID,
413
423
  },
414
424
  "summary": "Worker Fake worker @ 123412",
415
425
  }
@@ -458,7 +468,7 @@ def test_configure_load_model_configuration(mocker, responses):
458
468
  },
459
469
  "process": {
460
470
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
461
- "corpus": "11111111-1111-1111-1111-111111111111",
471
+ "corpus": CORPUS_ID,
462
472
  },
463
473
  "summary": "Worker Fake worker @ 123412",
464
474
  }
@@ -658,7 +668,7 @@ def test_find_extras_directory_not_found(monkeypatch, extras_path, exists, error
658
668
  def test_find_parents_file_paths(responses, mock_base_worker_with_cache, tmp_path):
659
669
  responses.add(
660
670
  responses.GET,
661
- "http://testserver/api/v1/task/my_task/from-agent/",
671
+ "http://testserver/api/v1/task/my_task/",
662
672
  status=200,
663
673
  json={"parents": ["first", "second", "third"]},
664
674
  )
@@ -669,15 +679,13 @@ def test_find_parents_file_paths(responses, mock_base_worker_with_cache, tmp_pat
669
679
  ):
670
680
  (tmp_path / parent_id).mkdir()
671
681
  file_path = tmp_path / parent_id / filename
672
- with file_path.open("w", encoding="utf-8") as f:
673
- f.write(content)
682
+ file_path.write_text(content)
674
683
 
675
684
  # Configure worker with a specific data directory
676
685
  mock_base_worker_with_cache.task_data_dir = tmp_path
677
686
  mock_base_worker_with_cache.args = mock_base_worker_with_cache.parser.parse_args()
678
687
 
679
688
  mock_base_worker_with_cache.configure()
680
- mock_base_worker_with_cache.configure_cache()
681
689
 
682
690
  assert mock_base_worker_with_cache.find_parents_file_paths(filename) == [
683
691
  tmp_path / "first" / filename,
@@ -754,3 +762,195 @@ def test_corpus_id_set_read_only_mode(
754
762
  mock_elements_worker_read_only.configure()
755
763
 
756
764
  assert mock_elements_worker_read_only.corpus_id == corpus_id
765
+
766
+
767
+ @pytest.mark.parametrize(
768
+ (
769
+ "wk_version_config",
770
+ "wk_version_user_config",
771
+ "frontend_user_config",
772
+ "model_config",
773
+ "expected_config",
774
+ ),
775
+ [
776
+ ({}, {}, {}, {}, {}),
777
+ # Keep parameters from worker version configuration
778
+ ({"parameter": 0}, {}, {}, {}, {"parameter": 0}),
779
+ # Keep parameters from worker version configuration + user_config defaults
780
+ (
781
+ {"parameter": 0},
782
+ {
783
+ "parameter2": {
784
+ "type": "int",
785
+ "title": "Lambda",
786
+ "default": 0,
787
+ "required": False,
788
+ }
789
+ },
790
+ {},
791
+ {},
792
+ {"parameter": 0, "parameter2": 0},
793
+ ),
794
+ # Keep parameters from worker version configuration + user_config no defaults
795
+ (
796
+ {"parameter": 0},
797
+ {
798
+ "parameter2": {
799
+ "type": "int",
800
+ "title": "Lambda",
801
+ "required": False,
802
+ }
803
+ },
804
+ {},
805
+ {},
806
+ {"parameter": 0},
807
+ ),
808
+ # Keep parameters from worker version configuration but user_config defaults overrides
809
+ (
810
+ {"parameter": 0},
811
+ {
812
+ "parameter": {
813
+ "type": "int",
814
+ "title": "Lambda",
815
+ "default": 1,
816
+ "required": False,
817
+ }
818
+ },
819
+ {},
820
+ {},
821
+ {"parameter": 1},
822
+ ),
823
+ # Keep parameters from worker version configuration + frontend config
824
+ (
825
+ {"parameter": 0},
826
+ {},
827
+ {"parameter2": 0},
828
+ {},
829
+ {"parameter": 0, "parameter2": 0},
830
+ ),
831
+ # Keep parameters from worker version configuration + frontend config overrides
832
+ ({"parameter": 0}, {}, {"parameter": 1}, {}, {"parameter": 1}),
833
+ # Keep parameters from worker version configuration + model config
834
+ (
835
+ {"parameter": 0},
836
+ {},
837
+ {},
838
+ {"parameter2": 0},
839
+ {"parameter": 0, "parameter2": 0},
840
+ ),
841
+ # Keep parameters from worker version configuration + model config overrides
842
+ ({"parameter": 0}, {}, {}, {"parameter": 1}, {"parameter": 1}),
843
+ # Keep parameters from worker version configuration + user_config default + model config overrides
844
+ (
845
+ {"parameter": 0},
846
+ {
847
+ "parameter": {
848
+ "type": "int",
849
+ "title": "Lambda",
850
+ "default": 1,
851
+ "required": False,
852
+ }
853
+ },
854
+ {},
855
+ {"parameter": 2},
856
+ {"parameter": 2},
857
+ ),
858
+ # Keep parameters from worker version configuration + model config + frontend config overrides
859
+ ({"parameter": 0}, {}, {"parameter": 2}, {"parameter": 1}, {"parameter": 2}),
860
+ # Keep parameters from worker version configuration + user_config default + model config + frontend config overrides all
861
+ (
862
+ {"parameter": 0},
863
+ {
864
+ "parameter": {
865
+ "type": "int",
866
+ "title": "Lambda",
867
+ "default": 1,
868
+ "required": False,
869
+ }
870
+ },
871
+ {"parameter": 3},
872
+ {"parameter": 2},
873
+ {"parameter": 3},
874
+ ),
875
+ ],
876
+ )
877
+ def test_worker_config_multiple_source(
878
+ monkeypatch,
879
+ responses,
880
+ wk_version_config,
881
+ wk_version_user_config,
882
+ frontend_user_config,
883
+ model_config,
884
+ expected_config,
885
+ ):
886
+ # Compute WorkerRun info
887
+ payload = {
888
+ "id": "56785678-5678-5678-5678-567856785678",
889
+ "parents": [],
890
+ "worker_version": {
891
+ "id": "12341234-1234-1234-1234-123412341234",
892
+ "configuration": {
893
+ "docker": {"image": "python:3"},
894
+ "configuration": wk_version_config,
895
+ "secrets": [],
896
+ "user_configuration": wk_version_user_config,
897
+ },
898
+ "revision": {
899
+ "hash": "deadbeef1234",
900
+ "name": "some git revision",
901
+ },
902
+ "docker_image": "python:3",
903
+ "docker_image_name": "python:3",
904
+ "state": "created",
905
+ "worker": {
906
+ "id": "deadbeef-1234-5678-1234-worker",
907
+ "name": "Fake worker",
908
+ "slug": "fake_worker",
909
+ "type": "classifier",
910
+ },
911
+ },
912
+ "configuration": {
913
+ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
914
+ "name": "Configuration entered by user",
915
+ "configuration": frontend_user_config,
916
+ },
917
+ "model_version": {
918
+ "id": "12341234-1234-1234-1234-123412341234",
919
+ "name": "Model version 1337",
920
+ "configuration": model_config,
921
+ "model": {
922
+ "id": "hahahaha-haha-haha-haha-hahahahahaha",
923
+ "name": "My model",
924
+ },
925
+ },
926
+ "process": {
927
+ "name": None,
928
+ "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeffff",
929
+ "state": "running",
930
+ "mode": "workers",
931
+ "corpus": CORPUS_ID,
932
+ "use_cache": False,
933
+ "activity_state": "ready",
934
+ "model_id": None,
935
+ "train_folder_id": None,
936
+ "validation_folder_id": None,
937
+ "test_folder_id": None,
938
+ },
939
+ "summary": "Worker Fake worker @ 123412",
940
+ }
941
+
942
+ responses.add(
943
+ responses.GET,
944
+ "http://testserver/api/v1/process/workers/56785678-5678-5678-5678-567856785678/",
945
+ status=200,
946
+ body=json.dumps(payload),
947
+ content_type="application/json",
948
+ )
949
+
950
+ # Create and configure a worker
951
+ monkeypatch.setattr(sys, "argv", ["worker"])
952
+ worker = BaseWorker()
953
+ worker.configure()
954
+
955
+ # Check final config
956
+ assert worker.config == expected_config