learning-loop-node 0.10.7__py3-none-any.whl → 0.10.9__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.

Potentially problematic release.


This version of learning-loop-node might be problematic. Click here for more details.

Files changed (55) hide show
  1. learning_loop_node/detector/detector_node.py +1 -1
  2. learning_loop_node/detector/outbox.py +67 -35
  3. learning_loop_node/detector/rest/outbox_mode.py +1 -1
  4. learning_loop_node/tests/annotator/conftest.py +50 -0
  5. learning_loop_node/{annotation/tests → tests/annotator}/test_annotator_node.py +9 -11
  6. learning_loop_node/{detector/tests → tests/detector}/conftest.py +30 -4
  7. learning_loop_node/{detector/inbox_filter/tests → tests/detector/inbox_filter}/test_observation.py +1 -1
  8. learning_loop_node/{detector/inbox_filter/tests → tests/detector/inbox_filter}/test_relevance_group.py +2 -7
  9. learning_loop_node/{detector/inbox_filter/tests → tests/detector/inbox_filter}/test_unexpected_observations_count.py +3 -6
  10. learning_loop_node/tests/detector/pytest.ini +10 -0
  11. learning_loop_node/{detector/tests → tests/detector}/test_client_communication.py +12 -9
  12. learning_loop_node/tests/detector/test_outbox.py +96 -0
  13. learning_loop_node/{detector/tests → tests/detector}/test_relevance_filter.py +8 -6
  14. learning_loop_node/{detector/tests → tests/detector}/testing_detector.py +3 -3
  15. learning_loop_node/tests/general/__init__.py +0 -0
  16. learning_loop_node/tests/general/conftest.py +62 -0
  17. learning_loop_node/tests/general/pytest.ini +10 -0
  18. learning_loop_node/tests/{test_data_classes.py → general/test_data_classes.py} +3 -3
  19. learning_loop_node/tests/{test_downloader.py → general/test_downloader.py} +24 -12
  20. learning_loop_node/tests/general/test_learning_loop_node.py +20 -0
  21. learning_loop_node/tests/test_helper.py +20 -9
  22. learning_loop_node/tests/trainer/__init__.py +0 -0
  23. learning_loop_node/{trainer/tests → tests/trainer}/conftest.py +32 -3
  24. learning_loop_node/tests/trainer/pytest.ini +10 -0
  25. learning_loop_node/{trainer/tests → tests/trainer}/state_helper.py +2 -1
  26. learning_loop_node/tests/trainer/states/__init__.py +0 -0
  27. learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_cleanup.py +2 -2
  28. learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_detecting.py +5 -5
  29. learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_download_train_model.py +3 -3
  30. learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_prepare.py +4 -4
  31. learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_sync_confusion_matrix.py +3 -4
  32. learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_train.py +4 -4
  33. learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_upload_detections.py +6 -6
  34. learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_upload_model.py +4 -4
  35. learning_loop_node/{trainer/tests → tests/trainer}/test_errors.py +3 -3
  36. learning_loop_node/{trainer/tests → tests/trainer}/test_trainer_states.py +4 -4
  37. learning_loop_node/{trainer/tests → tests/trainer}/testing_trainer_logic.py +2 -2
  38. learning_loop_node/{tests → trainer}/test_executor.py +1 -1
  39. learning_loop_node/trainer/trainer_node.py +5 -7
  40. {learning_loop_node-0.10.7.dist-info → learning_loop_node-0.10.9.dist-info}/METADATA +1 -1
  41. learning_loop_node-0.10.9.dist-info/RECORD +93 -0
  42. learning_loop_node/conftest.py +0 -89
  43. learning_loop_node/detector/tests/test_outbox.py +0 -86
  44. learning_loop_node/tests/conftest.py +0 -21
  45. learning_loop_node/tests/test_learning_loop_node.py +0 -18
  46. learning_loop_node-0.10.7.dist-info/RECORD +0 -87
  47. /learning_loop_node/{detector/tests → tests/annotator}/__init__.py +0 -0
  48. /learning_loop_node/{pytest.ini → tests/annotator/pytest.ini} +0 -0
  49. /learning_loop_node/{trainer/tests → tests/detector}/__init__.py +0 -0
  50. /learning_loop_node/{trainer/tests/states → tests/detector/inbox_filter}/__init__.py +0 -0
  51. /learning_loop_node/{detector/tests → tests/detector}/test.jpg +0 -0
  52. /learning_loop_node/tests/{test_data → general/test_data}/file_1.txt +0 -0
  53. /learning_loop_node/tests/{test_data → general/test_data}/file_2.txt +0 -0
  54. /learning_loop_node/tests/{test_data → general/test_data}/model.json +0 -0
  55. {learning_loop_node-0.10.7.dist-info → learning_loop_node-0.10.9.dist-info}/WHEEL +0 -0
@@ -0,0 +1,62 @@
1
+ import asyncio
2
+ import logging
3
+ import os
4
+ import shutil
5
+
6
+ import pytest
7
+
8
+ from ...data_classes import Context
9
+ from ...data_exchanger import DataExchanger
10
+ from ...globals import GLOBALS
11
+ from ...loop_communication import LoopCommunicator
12
+
13
+
14
+ @pytest.fixture(autouse=True, scope='function')
15
+ async def create_project_for_module():
16
+
17
+ loop_communicator = LoopCommunicator()
18
+ await loop_communicator.delete("/zauberzeug/projects/pytest_nodelib_general?keep_images=true")
19
+ await asyncio.sleep(1)
20
+ project_configuration = {
21
+ 'project_name': 'pytest_nodelib_general', 'inbox': 0, 'annotate': 0, 'review': 0, 'complete': 3, 'image_style': 'beautiful',
22
+ 'box_categories': 2, 'point_categories': 2, 'segmentation_categories': 2, 'thumbs': False, 'tags': 0,
23
+ 'trainings': 1, 'box_detections': 3, 'box_annotations': 0}
24
+ assert (await loop_communicator.post("/zauberzeug/projects/generator", json=project_configuration)).status_code == 200
25
+ yield
26
+ await loop_communicator.delete("/zauberzeug/projects/pytest_nodelib_general?keep_images=true")
27
+ await loop_communicator.shutdown()
28
+
29
+
30
+ @pytest.fixture()
31
+ async def data_exchanger():
32
+ loop_communicator = LoopCommunicator()
33
+ context = Context(organization='zauberzeug', project='pytest_nodelib_general')
34
+ dx = DataExchanger(context, loop_communicator)
35
+ yield dx
36
+ await loop_communicator.shutdown()
37
+
38
+ # ====================================== REDUNDANT FIXTURES IN ALL CONFTESTS ! ======================================
39
+
40
+
41
+ @pytest.fixture(autouse=True, scope='session')
42
+ def clear_loggers():
43
+ """Remove handlers from all loggers"""
44
+ # see https://github.com/pytest-dev/pytest/issues/5502
45
+ yield
46
+
47
+ loggers = [logging.getLogger()] + list(logging.Logger.manager.loggerDict.values())
48
+ for logger in loggers:
49
+ if not isinstance(logger, logging.Logger):
50
+ continue
51
+ handlers = getattr(logger, 'handlers', [])
52
+ for handler in handlers:
53
+ logger.removeHandler(handler)
54
+
55
+
56
+ @pytest.fixture(autouse=True, scope='function')
57
+ def data_folder():
58
+ GLOBALS.data_folder = '/tmp/learning_loop_lib_data'
59
+ shutil.rmtree(GLOBALS.data_folder, ignore_errors=True)
60
+ os.makedirs(GLOBALS.data_folder, exist_ok=True)
61
+ yield
62
+ shutil.rmtree(GLOBALS.data_folder, ignore_errors=True)
@@ -0,0 +1,10 @@
1
+ [pytest]
2
+ python_files = test_*.py
3
+ asyncio_mode = auto
4
+
5
+ cache_dir = /tmp/pytest_cache
6
+
7
+ # for debbuging tests:
8
+ ; log_cli_level = INFO
9
+ ; log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
10
+ ; log_cli_date_format=%Y-%m-%d %H:%M:%S
@@ -3,9 +3,9 @@ from dataclasses import asdict
3
3
  from dacite import from_dict
4
4
  from fastapi.encoders import jsonable_encoder
5
5
 
6
- from learning_loop_node.data_classes import (AnnotationData,
7
- AnnotationEventType, Category,
8
- Context, Point)
6
+ from ...data_classes import AnnotationData, AnnotationEventType, Category, Context, Point
7
+
8
+ # Used by all Nodes
9
9
 
10
10
 
11
11
  def test_basemodel_functionality():
@@ -1,27 +1,28 @@
1
1
  import os
2
2
  import shutil
3
3
 
4
- from learning_loop_node.data_classes import Context
5
- from learning_loop_node.data_exchanger import DataExchanger
6
- from learning_loop_node.globals import GLOBALS
4
+ from ...data_classes import Context
5
+ from ...data_exchanger import DataExchanger
6
+ from ...globals import GLOBALS
7
+ from ...helpers.misc import delete_corrupt_images
8
+ from .. import test_helper
7
9
 
8
- from ..helpers.misc import delete_corrupt_images
9
- from . import test_helper
10
+ # Used by all Nodes
10
11
 
11
12
 
12
13
  async def test_download_model(data_exchanger: DataExchanger):
13
14
 
14
- _, _, trainings_folder = test_helper.create_needed_folders()
15
- model_id = await test_helper.get_latest_model_id(project='pytest')
15
+ _, _, trainings_folder = create_needed_folders()
16
+ model_id = await test_helper.get_latest_model_id(project='pytest_nodelib_general')
16
17
 
17
- await data_exchanger.download_model(trainings_folder, Context(organization='zauberzeug', project='pytest'), model_id, 'mocked')
18
+ await data_exchanger.download_model(trainings_folder, Context(organization='zauberzeug', project='pytest_nodelib_general'), model_id, 'mocked')
18
19
 
19
20
  files = test_helper.get_files_in_folder(GLOBALS.data_folder)
20
21
  assert len(files) == 3, str(files)
21
22
 
22
- file_1 = f'{GLOBALS.data_folder}/zauberzeug/pytest/trainings/some_uuid/file_1.txt'
23
- file_2 = f'{GLOBALS.data_folder}/zauberzeug/pytest/trainings/some_uuid/file_2.txt'
24
- model_json = f'{GLOBALS.data_folder}/zauberzeug/pytest/trainings/some_uuid/model.json'
23
+ file_1 = f'{GLOBALS.data_folder}/zauberzeug/pytest_nodelib_general/trainings/some_uuid/file_1.txt'
24
+ file_2 = f'{GLOBALS.data_folder}/zauberzeug/pytest_nodelib_general/trainings/some_uuid/file_2.txt'
25
+ model_json = f'{GLOBALS.data_folder}/zauberzeug/pytest_nodelib_general/trainings/some_uuid/model.json'
25
26
 
26
27
  assert file_1 in files
27
28
  assert file_2 in files
@@ -39,7 +40,7 @@ async def test_fetching_image_ids(data_exchanger: DataExchanger):
39
40
 
40
41
 
41
42
  async def test_download_images(data_exchanger: DataExchanger):
42
- _, image_folder, _ = test_helper.create_needed_folders()
43
+ _, image_folder, _ = create_needed_folders()
43
44
  image_ids = await data_exchanger.fetch_image_uuids()
44
45
  await data_exchanger.download_images(image_ids, image_folder)
45
46
  files = test_helper.get_files_in_folder(GLOBALS.data_folder)
@@ -70,3 +71,14 @@ async def test_removal_of_corrupted_images(data_exchanger: DataExchanger):
70
71
 
71
72
  assert len(os.listdir('/tmp/img_folder')) == num_images if data_exchanger.check_jpeg else num_images - 1
72
73
  shutil.rmtree('/tmp/img_folder', ignore_errors=True)
74
+
75
+
76
+ # ---------------------- HELPERS
77
+
78
+
79
+ def create_needed_folders(training_uuid: str = 'some_uuid'): # pylint: disable=unused-argument
80
+ project_folder = test_helper.create_project_folder(
81
+ Context(organization='zauberzeug', project='pytest_nodelib_general'))
82
+ image_folder = test_helper.create_image_folder(project_folder)
83
+ training_folder = test_helper.create_training_folder(project_folder, training_uuid)
84
+ return project_folder, image_folder, training_folder
@@ -0,0 +1,20 @@
1
+ from typing import List
2
+
3
+ import pytest
4
+
5
+ from ...helpers.misc import create_resource_paths
6
+
7
+ # Used by all Nodes
8
+
9
+
10
+ @pytest.mark.parametrize("image_ids,expected_urls,expected_ids", [
11
+ (['some_id'], ['/zauberzeug/projects/pytest_nodelib_general/images/some_id/main'], ['some_id']),
12
+ (['some_id_1', 'some_id_2'], ['/zauberzeug/projects/pytest_nodelib_general/images/some_id_1/main',
13
+ '/zauberzeug/projects/pytest_nodelib_general/images/some_id_2/main'], ['some_id_1', 'some_id_2']),
14
+ ([], [], [])
15
+ ])
16
+ def test_resource_path_creation(image_ids: List[str], expected_urls: List[str], expected_ids: List['str']):
17
+ urls, ids = create_resource_paths('zauberzeug', 'pytest_nodelib_general', image_ids)
18
+
19
+ assert urls == expected_urls
20
+ assert ids == expected_ids
@@ -6,9 +6,10 @@ import zipfile
6
6
  from glob import glob
7
7
  from typing import Callable
8
8
 
9
- from learning_loop_node.data_classes import Context
10
- from learning_loop_node.helpers.misc import create_image_folder, create_project_folder, create_training_folder
11
- from learning_loop_node.loop_communication import LoopCommunicator
9
+ from ..data_classes import (BoxDetection, ClassificationDetection, Context, Detections, Point, PointDetection,
10
+ SegmentationDetection, Shape)
11
+ from ..helpers.misc import create_image_folder, create_project_folder, create_training_folder
12
+ from ..loop_communication import LoopCommunicator
12
13
 
13
14
 
14
15
  def get_files_in_folder(folder: str):
@@ -62,9 +63,19 @@ def _update_attribute_dict(obj: dict, **kwargs) -> None:
62
63
  obj[key] = value
63
64
 
64
65
 
65
- def create_needed_folders(training_uuid: str = 'some_uuid'): # pylint: disable=unused-argument
66
- project_folder = create_project_folder(
67
- Context(organization='zauberzeug', project='pytest'))
68
- image_folder = create_image_folder(project_folder)
69
- training_folder = create_training_folder(project_folder, training_uuid)
70
- return project_folder, image_folder, training_folder
66
+ def get_dummy_detections():
67
+ return Detections(
68
+ box_detections=[
69
+ BoxDetection(category_name='some_category_name', x=1, y=2, height=3, width=4,
70
+ model_name='some_model', confidence=.42, category_id='some_id')],
71
+ point_detections=[
72
+ PointDetection(category_name='some_category_name_2', x=10, y=12,
73
+ model_name='some_model', confidence=.42, category_id='some_id_2')],
74
+ segmentation_detections=[
75
+ SegmentationDetection(category_name='some_category_name_3',
76
+ shape=Shape(points=[Point(x=1, y=1)]),
77
+ model_name='some_model', confidence=.42,
78
+ category_id='some_id_3')],
79
+ classification_detections=[
80
+ ClassificationDetection(category_name='some_category_name_4', model_name='some_model',
81
+ confidence=.42, category_id='some_id_4')])
File without changes
@@ -1,3 +1,5 @@
1
+ from ...globals import GLOBALS
2
+ import shutil
1
3
  import logging
2
4
  import os
3
5
  import socket
@@ -6,9 +8,9 @@ from multiprocessing import log_to_stderr
6
8
  import icecream
7
9
  import pytest
8
10
 
9
- from learning_loop_node.data_classes import Context
10
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
11
- from learning_loop_node.trainer.trainer_node import TrainerNode
11
+ from ...data_classes import Context
12
+ from ...trainer.trainer_node import TrainerNode
13
+ from .testing_trainer_logic import TestingTrainerLogic
12
14
 
13
15
  # pylint: disable=protected-access
14
16
 
@@ -64,3 +66,30 @@ async def test_initialized_trainer():
64
66
  def is_port_in_use(port):
65
67
  with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
66
68
  return s.connect_ex(('localhost', port)) == 0
69
+
70
+
71
+ # ====================================== REDUNDANT FIXTURES IN ALL CONFTESTS ! ======================================
72
+
73
+
74
+ @pytest.fixture(autouse=True, scope='session')
75
+ def clear_loggers():
76
+ """Remove handlers from all loggers"""
77
+ # see https://github.com/pytest-dev/pytest/issues/5502
78
+ yield
79
+
80
+ loggers = [logging.getLogger()] + list(logging.Logger.manager.loggerDict.values())
81
+ for logger in loggers:
82
+ if not isinstance(logger, logging.Logger):
83
+ continue
84
+ handlers = getattr(logger, 'handlers', [])
85
+ for handler in handlers:
86
+ logger.removeHandler(handler)
87
+
88
+
89
+ @pytest.fixture(autouse=True, scope='function')
90
+ def data_folder():
91
+ GLOBALS.data_folder = '/tmp/learning_loop_lib_data'
92
+ shutil.rmtree(GLOBALS.data_folder, ignore_errors=True)
93
+ os.makedirs(GLOBALS.data_folder, exist_ok=True)
94
+ yield
95
+ shutil.rmtree(GLOBALS.data_folder, ignore_errors=True)
@@ -0,0 +1,10 @@
1
+ [pytest]
2
+ python_files = test_*.py
3
+ asyncio_mode = auto
4
+
5
+ cache_dir = /tmp/pytest_cache
6
+
7
+ # for debbuging tests:
8
+ ; log_cli_level = INFO
9
+ ; log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
10
+ ; log_cli_date_format=%Y-%m-%d %H:%M:%S
@@ -1,9 +1,10 @@
1
1
  import logging
2
2
 
3
- from learning_loop_node.data_classes import Training
4
3
  from learning_loop_node.tests.test_helper import condition, update_attributes
5
4
  from learning_loop_node.trainer.trainer_logic import TrainerLogic
6
5
 
6
+ from ...data_classes import Training
7
+
7
8
 
8
9
  def create_active_training_file(trainer: TrainerLogic, **kwargs) -> None:
9
10
  update_attributes(trainer._training, **kwargs) # pylint: disable=protected-access
File without changes
@@ -1,5 +1,5 @@
1
- from learning_loop_node.trainer.tests.state_helper import create_active_training_file
2
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
1
+ from ..state_helper import create_active_training_file
2
+ from ..testing_trainer_logic import TestingTrainerLogic
3
3
 
4
4
  # pylint: disable=protected-access
5
5
 
@@ -1,10 +1,10 @@
1
1
  import asyncio
2
2
 
3
- from learning_loop_node.conftest import get_dummy_detections
4
- from learning_loop_node.data_classes import TrainerState
5
- from learning_loop_node.trainer.tests.state_helper import assert_training_state, create_active_training_file
6
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
7
- from learning_loop_node.trainer.trainer_logic import TrainerLogic
3
+ from ....data_classes import TrainerState
4
+ from ....trainer.trainer_logic import TrainerLogic
5
+ from ...test_helper import get_dummy_detections
6
+ from ..state_helper import assert_training_state, create_active_training_file
7
+ from ..testing_trainer_logic import TestingTrainerLogic
8
8
 
9
9
  # pylint: disable=protected-access
10
10
  error_key = 'detecting'
@@ -2,9 +2,9 @@
2
2
  import asyncio
3
3
  import os
4
4
 
5
- from learning_loop_node.data_classes import TrainerState
6
- from learning_loop_node.trainer.tests.state_helper import assert_training_state, create_active_training_file
7
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
5
+ from ....data_classes import TrainerState
6
+ from ..state_helper import assert_training_state, create_active_training_file
7
+ from ..testing_trainer_logic import TestingTrainerLogic
8
8
 
9
9
  # pylint: disable=protected-access
10
10
 
@@ -1,9 +1,9 @@
1
1
  import asyncio
2
2
 
3
- from learning_loop_node.data_classes import Context, TrainerState
4
- from learning_loop_node.trainer.tests.state_helper import assert_training_state, create_active_training_file
5
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
6
- from learning_loop_node.trainer.trainer_logic import TrainerLogic
3
+ from ....data_classes import Context, TrainerState
4
+ from ....trainer.trainer_logic import TrainerLogic
5
+ from ..state_helper import assert_training_state, create_active_training_file
6
+ from ..testing_trainer_logic import TestingTrainerLogic
7
7
 
8
8
  # pylint: disable=protected-access
9
9
  error_key = 'prepare'
@@ -3,10 +3,9 @@ import asyncio
3
3
 
4
4
  from pytest_mock import MockerFixture # pip install pytest-mock
5
5
 
6
- from learning_loop_node.data_classes import TrainerState
7
- from learning_loop_node.trainer.trainer_logic import TrainerLogic
8
- from learning_loop_node.trainer.trainer_node import TrainerNode
9
-
6
+ from ....data_classes import TrainerState
7
+ from ....trainer.trainer_logic import TrainerLogic
8
+ from ....trainer.trainer_node import TrainerNode
10
9
  from ..state_helper import assert_training_state, create_active_training_file
11
10
  from ..testing_trainer_logic import TestingTrainerLogic
12
11
 
@@ -1,9 +1,9 @@
1
1
  import asyncio
2
2
 
3
- from learning_loop_node.data_classes import TrainerState
4
- from learning_loop_node.tests.test_helper import condition
5
- from learning_loop_node.trainer.tests.state_helper import assert_training_state, create_active_training_file
6
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
3
+ from ....data_classes import TrainerState
4
+ from ...test_helper import condition
5
+ from ..state_helper import assert_training_state, create_active_training_file
6
+ from ..testing_trainer_logic import TestingTrainerLogic
7
7
 
8
8
  # pylint: disable=protected-access
9
9
 
@@ -3,12 +3,12 @@ import asyncio
3
3
  import pytest
4
4
  from dacite import from_dict
5
5
 
6
- from learning_loop_node.conftest import get_dummy_detections
7
- from learning_loop_node.data_classes import BoxDetection, Context, Detections, TrainerState
8
- from learning_loop_node.loop_communication import LoopCommunicator
9
- from learning_loop_node.trainer.tests.state_helper import assert_training_state, create_active_training_file
10
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
11
- from learning_loop_node.trainer.trainer_logic import TrainerLogic
6
+ from ....data_classes import BoxDetection, Context, Detections, TrainerState
7
+ from ....loop_communication import LoopCommunicator
8
+ from ....trainer.trainer_logic import TrainerLogic
9
+ from ...test_helper import get_dummy_detections
10
+ from ..state_helper import assert_training_state, create_active_training_file
11
+ from ..testing_trainer_logic import TestingTrainerLogic
12
12
 
13
13
  # pylint: disable=protected-access
14
14
  error_key = 'upload_detections'
@@ -2,10 +2,10 @@ import asyncio
2
2
 
3
3
  from pytest_mock import MockerFixture
4
4
 
5
- from learning_loop_node.data_classes import Context, TrainerState
6
- from learning_loop_node.trainer.tests.state_helper import assert_training_state, create_active_training_file
7
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
8
- from learning_loop_node.trainer.trainer_logic import TrainerLogic
5
+ from ....data_classes import Context, TrainerState
6
+ from ....trainer.trainer_logic import TrainerLogic
7
+ from ..state_helper import assert_training_state, create_active_training_file
8
+ from ..testing_trainer_logic import TestingTrainerLogic
9
9
 
10
10
  # pylint: disable=protected-access
11
11
  error_key = 'upload_model'
@@ -3,9 +3,9 @@ import re
3
3
 
4
4
  import pytest
5
5
 
6
- from learning_loop_node.data_classes import TrainerState
7
- from learning_loop_node.trainer.tests.state_helper import assert_training_state, create_active_training_file
8
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
6
+ from ...data_classes import TrainerState
7
+ from .state_helper import assert_training_state, create_active_training_file
8
+ from .testing_trainer_logic import TestingTrainerLogic
9
9
 
10
10
  # pylint: disable=protected-access
11
11
 
@@ -1,10 +1,10 @@
1
1
 
2
2
  from uuid import uuid4
3
3
 
4
- from learning_loop_node.data_classes import Context, TrainerState, Training
5
- from learning_loop_node.trainer.io_helpers import LastTrainingIO
6
- from learning_loop_node.trainer.tests.testing_trainer_logic import TestingTrainerLogic
7
- from learning_loop_node.trainer.trainer_node import TrainerNode
4
+ from ...data_classes import Context, TrainerState, Training
5
+ from ...trainer.io_helpers import LastTrainingIO
6
+ from ...trainer.trainer_node import TrainerNode
7
+ from .testing_trainer_logic import TestingTrainerLogic
8
8
 
9
9
 
10
10
  def create_training() -> Training:
@@ -2,8 +2,8 @@ import asyncio
2
2
  import time
3
3
  from typing import Dict, List, Optional
4
4
 
5
- from learning_loop_node.data_classes import Context, Detections, ModelInformation, PretrainedModel, TrainingStateData
6
- from learning_loop_node.trainer.trainer_logic import TrainerLogic
5
+ from ...data_classes import Context, Detections, ModelInformation, PretrainedModel, TrainingStateData
6
+ from ...trainer.trainer_logic import TrainerLogic
7
7
 
8
8
 
9
9
  class TestingTrainerLogic(TrainerLogic):
@@ -6,7 +6,7 @@ from uuid import uuid4
6
6
  import psutil
7
7
  import pytest
8
8
 
9
- from learning_loop_node.trainer.executor import Executor
9
+ from .executor import Executor
10
10
 
11
11
 
12
12
  @pytest.fixture(autouse=True)
@@ -1,9 +1,8 @@
1
- import asyncio
2
1
  from dataclasses import asdict
3
2
  from typing import Dict, Optional
4
3
 
5
4
  from fastapi.encoders import jsonable_encoder
6
- from socketio import AsyncClient
5
+ from socketio import AsyncClient, exceptions
7
6
 
8
7
  from ..data_classes import TrainingStatus
9
8
  from ..node import Node
@@ -39,12 +38,11 @@ class TrainerNode(Node):
39
38
  if await self.trainer_logic.try_continue_run_if_incomplete():
40
39
  return # NOTE: we prevent sending idle status after starting a continuation
41
40
  await self.send_status()
41
+ except exceptions.TimeoutError:
42
+ self.log.warning('timeout when sending status to learning loop, reconnecting sio_client')
43
+ await self.sio_client.disconnect() # NOTE: reconnect happens in node._on_repeat
42
44
  except Exception as e:
43
- if isinstance(e, asyncio.TimeoutError):
44
- self.log.warning('timeout when sending status to learning loop, reconnecting sio_client')
45
- await self.sio_client.disconnect() # NOTE: reconnect happens in node._on_repeat
46
- else:
47
- self.log.exception(f'could not send status state: {e}')
45
+ self.log.exception(f'could not send status state: {e}')
48
46
 
49
47
  # ---------------------------------------------- NODE METHODS ---------------------------------------------------
50
48
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: learning-loop-node
3
- Version: 0.10.7
3
+ Version: 0.10.9
4
4
  Summary: Python Library for Nodes which connect to the Zauberzeug Learning Loop
5
5
  Home-page: https://github.com/zauberzeug/learning_loop_node
6
6
  License: MIT
@@ -0,0 +1,93 @@
1
+ learning_loop_node/__init__.py,sha256=onN5s8-x_xBsCM6NLmJO0Ym1sJHeCFaGw8qb0oQZmz8,364
2
+ learning_loop_node/annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ learning_loop_node/annotation/annotator_logic.py,sha256=BTaopkJZkIf1CI5lfsVKsxbxoUIbDJrevavuQUT5e_c,1000
4
+ learning_loop_node/annotation/annotator_node.py,sha256=wk11CQtM3A0Dr7efCn_Mw2X7ql5xn2sgEJzrIeSBC6Q,4043
5
+ learning_loop_node/data_classes/__init__.py,sha256=wCX88lDgbb8V-gtVCVe9i-NvvZuMe5FX7eD_UJgYYXw,1305
6
+ learning_loop_node/data_classes/annotations.py,sha256=iInU0Nuy_oYT_sj4k_n-W0UShCBI2cHQYrt8imymbtM,1211
7
+ learning_loop_node/data_classes/detections.py,sha256=1BcU5PNzIbryWcj2xJ6ysLBTBwGOdv9SxSJiUG8WEmw,4349
8
+ learning_loop_node/data_classes/general.py,sha256=44GJrJvGfPwDUmRsS7If9uSlE6KPP50LGUX91VzesLw,4664
9
+ learning_loop_node/data_classes/socket_response.py,sha256=tIdt-oYf6ULoJIDYQCecNM9OtWR6_wJ9tL0Ksu83Vko,655
10
+ learning_loop_node/data_classes/training.py,sha256=hnMHZMk-WNRERyo7U97qL09v1tIdhnzPfTH-JgifLwU,6164
11
+ learning_loop_node/data_exchanger.py,sha256=BTrXwjNkG9KgtUxil_ijMggql8sZDKXQm26xdKQr8_0,8459
12
+ learning_loop_node/detector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ learning_loop_node/detector/detector_logic.py,sha256=se0jRFbV7BfTvCuCI3gcUllSYIZ5dxTkvdISe6pPTRg,1660
14
+ learning_loop_node/detector/detector_node.py,sha256=jaz4TiHNVFd8p7NQ6Zcrsro9c-X9EHmmWXpFXAiO4G4,16695
15
+ learning_loop_node/detector/inbox_filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ learning_loop_node/detector/inbox_filter/cam_observation_history.py,sha256=TD346I9ymtIP0_CJXCIKMRuiXbfVVanXNu_iHAwDd7Q,3318
17
+ learning_loop_node/detector/inbox_filter/relevance_filter.py,sha256=s2FuwZ-tD_5obkSutstjc8pE_hLGbrv9WjrEO9t8rJ8,1011
18
+ learning_loop_node/detector/outbox.py,sha256=kRC_ZSvNNxEeJg0qmImBWNiKYjcgHiPAmRQB4VlQ-Uk,7828
19
+ learning_loop_node/detector/rest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ learning_loop_node/detector/rest/about.py,sha256=-PNqlQI_tzRvoSI_UR9rX8-5GeiENNpRDQ4Ylw3wYVs,607
21
+ learning_loop_node/detector/rest/backdoor_controls.py,sha256=38axRG66Z3_Q6bYKa7Hw-ldChEAu-dJcBM_Sl_17Ozo,1725
22
+ learning_loop_node/detector/rest/detect.py,sha256=8Rl1swANKgHc42P1z75t_PErQxpCKKPdAsKqDIZgdNU,1873
23
+ learning_loop_node/detector/rest/operation_mode.py,sha256=eIo6_56qyZECftf4AEN8wJMABIojC0TRazvWeg0Uj_s,1664
24
+ learning_loop_node/detector/rest/outbox_mode.py,sha256=anSZHB6jliz1t3fxrmEzgwNB62UHNdWNc9ZYOc5Nn9s,1018
25
+ learning_loop_node/detector/rest/upload.py,sha256=IPzxJPayD7_Gx5uYC1lVJwWxdnQgM8MYGa5NugXVosY,544
26
+ learning_loop_node/examples/novelty_score_updater.py,sha256=1DRgM9lxjFV-q2JvGDDsNLz_ic_rhEZ9wc6ZdjcxwPE,2038
27
+ learning_loop_node/globals.py,sha256=tgw_8RYOipPV9aYlyUhYtXfUxvJKRvfUk6u-qVAtZmY,174
28
+ learning_loop_node/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ learning_loop_node/helpers/environment_reader.py,sha256=OtCTDc0KT9r-SMygkZB_Mw-ZIJPfUZVyUzHJoDCgJP8,1658
30
+ learning_loop_node/helpers/gdrive_downloader.py,sha256=zeYJciTAJVRpu_eFjwgYLCpIa6hU1d71anqEBb564Rk,1145
31
+ learning_loop_node/helpers/log_conf.py,sha256=3yd-jaMOeD5cRIgA5w_BH2L5odf8c4-ZjD89Bdqwe44,824
32
+ learning_loop_node/helpers/misc.py,sha256=j4is8Rv0ttnCqF-R-wP3xwEi67OI6IBJav5Woo5lyDk,7701
33
+ learning_loop_node/loop_communication.py,sha256=rG5MdavSTaREZ6OWfAUIT_qkkYPw3is2_FujLmHQeIc,6576
34
+ learning_loop_node/node.py,sha256=pJg3mO7Egwtu7ewzWWgEXMtCG17u7yZjFt-KeN9n7rM,8010
35
+ learning_loop_node/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ learning_loop_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ learning_loop_node/tests/annotator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ learning_loop_node/tests/annotator/conftest.py,sha256=G4ZvdZUdvPp9bYCzg3eEVkGCeXn9INZ3AcN7d5CyLkU,1931
39
+ learning_loop_node/tests/annotator/pytest.ini,sha256=8QdjmawLy1zAzXrJ88or1kpFDhJw0W5UOnDfGGs_igU,262
40
+ learning_loop_node/tests/annotator/test_annotator_node.py,sha256=TPNPPrQAxQ_zEecQcH7hlczgD3ABtTCNtUvWD1_oApk,1985
41
+ learning_loop_node/tests/detector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ learning_loop_node/tests/detector/conftest.py,sha256=noWJWPaM9T2Shgs1I5KRDzszjPz2qTRmE1kqLaGMIdY,4161
43
+ learning_loop_node/tests/detector/inbox_filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
+ learning_loop_node/tests/detector/inbox_filter/test_observation.py,sha256=k4WYdvnuV7d_r7zI4M2aA8WuBjm0aycQ0vj1rGE2q4w,1370
45
+ learning_loop_node/tests/detector/inbox_filter/test_relevance_group.py,sha256=XjiMsS0LgvM0OkPf5-s2rjFbG7C42LTmz_rDVMGHKoY,7603
46
+ learning_loop_node/tests/detector/inbox_filter/test_unexpected_observations_count.py,sha256=MWC7PbaCy14jjRw0_oilkXj6gymAsUZXHJdzNW5m2D4,1639
47
+ learning_loop_node/tests/detector/pytest.ini,sha256=8QdjmawLy1zAzXrJ88or1kpFDhJw0W5UOnDfGGs_igU,262
48
+ learning_loop_node/tests/detector/test.jpg,sha256=msA-vHPmvPiro_D102Qmn1fn4vNfooqYYEXPxZUmYpk,161390
49
+ learning_loop_node/tests/detector/test_client_communication.py,sha256=fnTyzP3XV1i6YwB9-GEDj2ifc_Fr_FtnjDhPoRYX2Ec,5261
50
+ learning_loop_node/tests/detector/test_outbox.py,sha256=1sqTLRrCkUsoYz67Z1L03wIet1N3Nxlil3b5VLEK644,2995
51
+ learning_loop_node/tests/detector/test_relevance_filter.py,sha256=3VLhHKaxPzLYmiNZagvgg9ZHkPhWk4_-qpmkJw36wBU,2046
52
+ learning_loop_node/tests/detector/testing_detector.py,sha256=FeQroV85IvsT8dmalQBqf1FLNt_buCtZK3-lgtmbrBI,542
53
+ learning_loop_node/tests/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ learning_loop_node/tests/general/conftest.py,sha256=oVuE-XZfUPjOXE8KLJgDbIMKIF9Mmgfna2rlupC44TE,2298
55
+ learning_loop_node/tests/general/pytest.ini,sha256=8QdjmawLy1zAzXrJ88or1kpFDhJw0W5UOnDfGGs_igU,262
56
+ learning_loop_node/tests/general/test_data/file_1.txt,sha256=Lis06nfvbFPVCBZyEgQlfI_Nle2YDq1GQBlYvEfFtxw,19
57
+ learning_loop_node/tests/general/test_data/file_2.txt,sha256=Xp8EETGhZBdVAgb4URowSSpOytwwwJdV0Renkdur7R8,19
58
+ learning_loop_node/tests/general/test_data/model.json,sha256=_xNDucGOWila8gWnu8yFfrqmQ45Xq-_39eLKzjRtvpE,516
59
+ learning_loop_node/tests/general/test_data_classes.py,sha256=u5GoXNk2yqCp1EVm9YoBnYreL2SCjgJ0a3x01JQDOuM,701
60
+ learning_loop_node/tests/general/test_downloader.py,sha256=C6b_wG3TfQX53lmuanpH1yaQAdATFGXOmQ1nzXWqNss,3315
61
+ learning_loop_node/tests/general/test_learning_loop_node.py,sha256=SZd-VChpWnnsPN46pr4E_LL3ZevYx6psU-AWdVeOFpQ,770
62
+ learning_loop_node/tests/test_helper.py,sha256=nTynYtuUaK2hKh87pk7t7AIJaOiD3wJ5d6nCPqnwRMk,3012
63
+ learning_loop_node/tests/trainer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
+ learning_loop_node/tests/trainer/conftest.py,sha256=7nncnC2ZApakdyta9TMUfk0sgr_nyZhGFYCHuUlBlFI,3356
65
+ learning_loop_node/tests/trainer/pytest.ini,sha256=8QdjmawLy1zAzXrJ88or1kpFDhJw0W5UOnDfGGs_igU,262
66
+ learning_loop_node/tests/trainer/state_helper.py,sha256=MDe9opeKruip74FoRFff8MSWGiQNFqDpPtIEIbgPnFc,919
67
+ learning_loop_node/tests/trainer/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
+ learning_loop_node/tests/trainer/states/test_state_cleanup.py,sha256=gZNxSSwnj9f0esExNnQzqadM6-sE3IsF5sNbD0bZNu8,1250
69
+ learning_loop_node/tests/trainer/states/test_state_detecting.py,sha256=nvhkjBnGZgGVyomvPDcXuBR_WLqC4-QD2qE5enWiJ-g,3724
70
+ learning_loop_node/tests/trainer/states/test_state_download_train_model.py,sha256=aJBh0ksz9g2kQ3qqk8yrX-50kdRS4I7ZaeeFkr9CR3c,2863
71
+ learning_loop_node/tests/trainer/states/test_state_prepare.py,sha256=yaDhT-1676asGfgqhK2mfdoktAgeyWUwc2h0xyOoWzQ,2340
72
+ learning_loop_node/tests/trainer/states/test_state_sync_confusion_matrix.py,sha256=0Ak5bU2uiqRDSEzVSTBEoT9GN5UgL7SqBqJRyyxjmWE,4727
73
+ learning_loop_node/tests/trainer/states/test_state_train.py,sha256=dQDUvVI_FUYdLWm11F_7WxGge30l0OvML40Hil9r--k,3149
74
+ learning_loop_node/tests/trainer/states/test_state_upload_detections.py,sha256=U2qK1Vbzb0yBMBYNvB815AYBD6MsII7wxzYJrwFnUHQ,7554
75
+ learning_loop_node/tests/trainer/states/test_state_upload_model.py,sha256=u_YXELOWOXoaU4v41jgr3jHPWVFeVbe330k8GCEL9K0,3659
76
+ learning_loop_node/tests/trainer/test_errors.py,sha256=Z3BWvUkVKxMGe_RNYeVbrhPps7ylek3qS1zK2FpdMmU,2165
77
+ learning_loop_node/tests/trainer/test_trainer_states.py,sha256=djYCs5ieajQHRjk8QcUVBUkQEG8UGYFoNGwSX0z2oGk,1067
78
+ learning_loop_node/tests/trainer/testing_trainer_logic.py,sha256=KslqDJDntkgH4Yd_z-guiVPvzi5Q-l-Bqc3fUjT5N7U,3883
79
+ learning_loop_node/trainer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
+ learning_loop_node/trainer/downloader.py,sha256=qzx7zzObcFEvRVQFe8gi8KJNIapASi1_XssbspXD1Rw,1469
81
+ learning_loop_node/trainer/exceptions.py,sha256=hLLDGncC6PLZjKg4lZBpu-QA8itQIxiuxExz1uptgnw,40
82
+ learning_loop_node/trainer/executor.py,sha256=-0BxDqmAI1NCiISi7Rw8McJQfgxxVy1gSa1epYuL3U0,3942
83
+ learning_loop_node/trainer/io_helpers.py,sha256=Ylxz8HAId0Jlz95So5kXdJEp1yKQuwroDKIhbTUscF4,7257
84
+ learning_loop_node/trainer/rest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
+ learning_loop_node/trainer/rest/backdoor_controls.py,sha256=YQcG0KwxzKDNYeMtHrSwr26q__N7ty0o6Kar6CLWAd0,5869
86
+ learning_loop_node/trainer/rest/controls.py,sha256=XF37i2edeMHKdSXyJc4ZqaTZ38u6d3u3Sb3C-Mwyfko,934
87
+ learning_loop_node/trainer/test_executor.py,sha256=6BVGDN_6f5GEMMEvDLSG1yzMybSvgXaP5uYpSfsVPP0,2224
88
+ learning_loop_node/trainer/trainer_logic.py,sha256=PJxiO1chPdvpq8UTtzv_nVam9CouCswX9b1FnRwT2Tw,8411
89
+ learning_loop_node/trainer/trainer_logic_generic.py,sha256=AzllMMiUPP_CMkjIVqse8wY50Cg5RDnk5y5ERVUjtZg,25801
90
+ learning_loop_node/trainer/trainer_node.py,sha256=dV-kcTIxhHsep_xIXdGc_AaeJM1mFlQNnwUpTkG4btg,4110
91
+ learning_loop_node-0.10.9.dist-info/METADATA,sha256=DaJ_D49CGjlIbcX1xagMN3DPRxasYxFWiZBfDJqph5A,10383
92
+ learning_loop_node-0.10.9.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
93
+ learning_loop_node-0.10.9.dist-info/RECORD,,