learning-loop-node 0.10.8__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.
- learning_loop_node/detector/detector_node.py +1 -1
- learning_loop_node/detector/outbox.py +65 -33
- learning_loop_node/detector/rest/outbox_mode.py +1 -1
- learning_loop_node/tests/annotator/conftest.py +50 -0
- learning_loop_node/{annotation/tests → tests/annotator}/test_annotator_node.py +9 -11
- learning_loop_node/{detector/tests → tests/detector}/conftest.py +30 -4
- learning_loop_node/{detector/inbox_filter/tests → tests/detector/inbox_filter}/test_observation.py +1 -1
- learning_loop_node/{detector/inbox_filter/tests → tests/detector/inbox_filter}/test_relevance_group.py +2 -7
- learning_loop_node/{detector/inbox_filter/tests → tests/detector/inbox_filter}/test_unexpected_observations_count.py +3 -6
- learning_loop_node/tests/detector/pytest.ini +10 -0
- learning_loop_node/{detector/tests → tests/detector}/test_client_communication.py +12 -9
- learning_loop_node/tests/detector/test_outbox.py +96 -0
- learning_loop_node/{detector/tests → tests/detector}/test_relevance_filter.py +8 -6
- learning_loop_node/{detector/tests → tests/detector}/testing_detector.py +3 -3
- learning_loop_node/tests/general/__init__.py +0 -0
- learning_loop_node/tests/general/conftest.py +62 -0
- learning_loop_node/tests/general/pytest.ini +10 -0
- learning_loop_node/tests/{test_data_classes.py → general/test_data_classes.py} +3 -3
- learning_loop_node/tests/{test_downloader.py → general/test_downloader.py} +24 -12
- learning_loop_node/tests/general/test_learning_loop_node.py +20 -0
- learning_loop_node/tests/test_helper.py +20 -9
- learning_loop_node/tests/trainer/__init__.py +0 -0
- learning_loop_node/{trainer/tests → tests/trainer}/conftest.py +32 -3
- learning_loop_node/tests/trainer/pytest.ini +10 -0
- learning_loop_node/{trainer/tests → tests/trainer}/state_helper.py +2 -1
- learning_loop_node/tests/trainer/states/__init__.py +0 -0
- learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_cleanup.py +2 -2
- learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_detecting.py +5 -5
- learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_download_train_model.py +3 -3
- learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_prepare.py +4 -4
- learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_sync_confusion_matrix.py +3 -4
- learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_train.py +4 -4
- learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_upload_detections.py +6 -6
- learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_upload_model.py +4 -4
- learning_loop_node/{trainer/tests → tests/trainer}/test_errors.py +3 -3
- learning_loop_node/{trainer/tests → tests/trainer}/test_trainer_states.py +4 -4
- learning_loop_node/{trainer/tests → tests/trainer}/testing_trainer_logic.py +2 -2
- learning_loop_node/{tests → trainer}/test_executor.py +1 -1
- learning_loop_node/trainer/trainer_node.py +5 -7
- {learning_loop_node-0.10.8.dist-info → learning_loop_node-0.10.9.dist-info}/METADATA +1 -1
- learning_loop_node-0.10.9.dist-info/RECORD +93 -0
- learning_loop_node/conftest.py +0 -89
- learning_loop_node/detector/tests/test_outbox.py +0 -86
- learning_loop_node/tests/conftest.py +0 -21
- learning_loop_node/tests/test_learning_loop_node.py +0 -18
- learning_loop_node-0.10.8.dist-info/RECORD +0 -87
- /learning_loop_node/{detector/tests → tests/annotator}/__init__.py +0 -0
- /learning_loop_node/{pytest.ini → tests/annotator/pytest.ini} +0 -0
- /learning_loop_node/{trainer/tests → tests/detector}/__init__.py +0 -0
- /learning_loop_node/{trainer/tests/states → tests/detector/inbox_filter}/__init__.py +0 -0
- /learning_loop_node/{detector/tests → tests/detector}/test.jpg +0 -0
- /learning_loop_node/tests/{test_data → general/test_data}/file_1.txt +0 -0
- /learning_loop_node/tests/{test_data → general/test_data}/file_2.txt +0 -0
- /learning_loop_node/tests/{test_data → general/test_data}/model.json +0 -0
- {learning_loop_node-0.10.8.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
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
5
|
-
from
|
|
6
|
-
from
|
|
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
|
-
|
|
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 =
|
|
15
|
-
model_id = await test_helper.get_latest_model_id(project='
|
|
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='
|
|
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/
|
|
23
|
-
file_2 = f'{GLOBALS.data_folder}/zauberzeug/
|
|
24
|
-
model_json = f'{GLOBALS.data_folder}/zauberzeug/
|
|
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, _ =
|
|
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
|
|
10
|
-
|
|
11
|
-
from
|
|
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
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
|
10
|
-
from
|
|
11
|
-
from
|
|
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
|
|
2
|
-
from
|
|
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
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
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'
|
learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_download_train_model.py
RENAMED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import asyncio
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
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
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
from
|
|
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'
|
learning_loop_node/{trainer/tests → tests/trainer}/states/test_state_sync_confusion_matrix.py
RENAMED
|
@@ -3,10 +3,9 @@ import asyncio
|
|
|
3
3
|
|
|
4
4
|
from pytest_mock import MockerFixture # pip install pytest-mock
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
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
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
from
|
|
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
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
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
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
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
|
|
7
|
-
from
|
|
8
|
-
from
|
|
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
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
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
|
|
6
|
-
from
|
|
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):
|
|
@@ -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
|
-
|
|
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
|
|
|
@@ -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,,
|