Skip to content

Commit

Permalink
Merge pull request #9 from Toloka/autosync
Browse files Browse the repository at this point in the history
toloka-kit 0.1.3
  • Loading branch information
Losik authored Mar 1, 2021
2 parents 06d4b45 + 38b0439 commit 1d244a6
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 13 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
1.1.3
-------------------
* Added support for trainings
* Introduced `get_assignments_df` method

1.1.2
-------------------
* Introduced template builder support
* Introduced `get_analytics` method
* Sensitive values such as rewards and bonuses are now represented as decimal.Decimal
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ Main advantages of Toloka:

Get Started and Documentation
--------------
Installing toloka-kit is as easy as `pip install toloka-kit`

Usage examples are available [here](https://github.com/Toloka/toloka-kit/tree/main/examples)

All Toloka documentation is available [here](https://yandex.com/dev/toloka/doc/concepts/about.html?lang=en).


Expand Down
2 changes: 1 addition & 1 deletion src/client/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__title__ = 'toloka-kit'
__version__ = '0.1.2'
__version__ = '0.1.3'
__license__ = 'Apache 2.0'
1 change: 1 addition & 0 deletions src/client/aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@unique
class AggregatedSolutionType(Enum):
WEIGHTED_DYNAMIC_OVERLAP = 'WEIGHTED_DYNAMIC_OVERLAP'
DAWID_SKENE = 'DAWID_SKENE'


class PoolAggregatedSolutionRequest(BaseTolokaObject):
Expand Down
22 changes: 20 additions & 2 deletions src/client/project/template_builder/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, List, Any
from typing import Dict, List, Any, Union, Tuple

from . import actions # noqa: F401
from . import base # noqa: F401
Expand All @@ -9,12 +9,30 @@
from . import layouts # noqa: F401
from . import plugins # noqa: F401
from . import view # noqa: F401
from .base import BaseComponent, base_component_or
from .base import ComponentType, BaseComponent, base_component_or
from ..field_spec import FieldSpec, JsonSpec
from ...primitives.base import BaseTolokaObject
from ...util import traverse_dicts_recursively


class TemplateBuilder(BaseTolokaObject):

view: BaseComponent
plugins: List[BaseComponent]
vars: Dict[str, base_component_or(Any)]


def get_input_and_output(tb_config: Union[dict, TemplateBuilder]) -> Tuple[Dict[str, FieldSpec], Dict[str, FieldSpec]]:
input_spec = {}
output_spec = {}

if isinstance(tb_config, TemplateBuilder):
tb_config = tb_config.unstructure()

for obj in traverse_dicts_recursively(tb_config):
if obj.get('type') == ComponentType.DATA_INPUT.value:
input_spec[obj['path']] = JsonSpec()
elif obj.get('type') == ComponentType.DATA_OUTPUT.value:
output_spec[obj['path']] = JsonSpec()

return input_spec, output_spec
7 changes: 6 additions & 1 deletion src/client/project/template_builder/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, Tuple, Union

from ...primitives.base import BaseTolokaObject
from ..field_spec import FieldSpec
from .base import BaseComponent


Expand Down Expand Up @@ -33,3 +34,7 @@ class TemplateBuilder(BaseTolokaObject):
view: Optional[BaseComponent]
plugins: Optional[List[BaseComponent]]
vars: Optional[Dict[str, Any]]

def get_input_and_output(
tb_config: Union[dict, TemplateBuilder]
) -> Tuple[Dict[str, FieldSpec], Dict[str, FieldSpec]]: ...
4 changes: 2 additions & 2 deletions src/client/project/template_builder/conditions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Any
from typing import List, Any, Dict

from .base import BaseComponent, ComponentType, VersionedBaseComponent, base_component_or

Expand Down Expand Up @@ -46,7 +46,7 @@ class RequiredConditionV1(BaseConditionV1, spec_value=ComponentType.CONDITION_RE

class SchemaConditionV1(BaseConditionV1, spec_value=ComponentType.CONDITION_SCHEMA):
data: base_component_or(Any)
schema: dict # TODO: support base_component_or(Dict)
schema: Dict # TODO: support base_component_or(Dict)


class SubArrayConditionV1(BaseConditionV1, spec_value=ComponentType.CONDITION_SUB_ARRAY):
Expand Down
4 changes: 2 additions & 2 deletions src/client/project/template_builder/conditions.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,14 @@ class SchemaConditionV1(BaseConditionV1):
version: Optional[str] = ...,
hint: Optional[Any] = ...,
data: Optional[Any] = ...,
schema: Optional[dict] = ...
schema: Optional[Dict] = ...
) -> None: ...

_unexpected: Optional[Dict[str, Any]]
version: Optional[str]
hint: Optional[Any]
data: Optional[Any]
schema: Optional[dict]
schema: Optional[Dict]

class SubArrayConditionV1(BaseConditionV1):
"""Checks that the array in data is a subarray for parent.
Expand Down
1 change: 0 additions & 1 deletion src/client/project/template_builder/fields.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,6 @@ class FileFieldV1(BaseFieldV1):
If a user logs in from a mobile device, it's more convenient to use field.media-file — it's adapted for mobile
devices and makes it easier to upload photos and videos.
Attributes:
data: Data with values that will be processed or changed.
label: Label above the component.
Expand Down
4 changes: 2 additions & 2 deletions src/client/training.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Training(BaseTolokaObject):
training_tasks_in_task_suite_count: Optional[int] = ...,
task_suites_required_to_pass: Optional[int] = ...,
retry_training_after_days: Optional[int] = ...,
inherited_instructions: Optional[str] = ...,
inherited_instructions: Optional[bool] = ...,
public_instructions: Optional[str] = ...,
metadata: Optional[Dict[str, List[str]]] = ...,
owner: Optional[Owner] = ...,
Expand All @@ -71,7 +71,7 @@ class Training(BaseTolokaObject):
training_tasks_in_task_suite_count: Optional[int]
task_suites_required_to_pass: Optional[int]
retry_training_after_days: Optional[int]
inherited_instructions: Optional[str]
inherited_instructions: Optional[bool]
public_instructions: Optional[str]
metadata: Optional[Dict[str, List[str]]]
owner: Optional[Owner]
Expand Down
106 changes: 105 additions & 1 deletion tests/template_builder/test_template_builder.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import pytest
import json

from toloka.client.project.field_spec import JsonSpec
from toloka.client.project.view_spec import ViewSpec
from toloka.client.project.template_builder import TemplateBuilder
from toloka.client.project.template_builder import TemplateBuilder, get_input_and_output
from toloka.client.project.template_builder.actions import SetActionV1
from toloka.client.project.template_builder.base import RefComponent
from toloka.client.project.template_builder.conditions import RequiredConditionV1
Expand Down Expand Up @@ -256,3 +257,106 @@ def test_inconsistent_versions(view_spec_map, new_version):
with pytest.raises(ValueError) as excinfo:
result.config.view.items[0].version = new_version
assert excinfo.value.args[0] == 'only v1 components are supported'


def test_get_input_and_output():
tb_config = TemplateBuilder(
view=SideBySideLayoutV1(
version='1.0.0',
controls=ListViewV1(
version='1.0.0',
items=[
RadioGroupFieldV1(
version='1.0.0',
data=RefComponent(
ref='vars.0'
),
label='Какое фото вам больше нравится?',
options=[
GroupFieldOption(
label='A',
value='a'
),
GroupFieldOption(
label='B',
value='b',
hint=TextareaFieldV1(
data=InputData(
path='text'
),
version='1.0.0'
)
),
GroupFieldOption(
label='Картинки не загрузились',
value='failure'
)
],
),
TextareaFieldV1(
version='1.0.0',
data=OutputData(
path='why'
),
label=InputData(
path='text'
),
validation=RequiredConditionV1(
version='1.0.0'
)
)
]
),
items=[
ImageViewV1(
version='1.2.3',
url=InputData(
path='image_a',
),
full_height=True
),
ImageViewV1(
version='1.2.3',
url=InputData(
path='image_b'
),
full_height=True
)
]
),
plugins=[
HotkeysPluginV1(
version='1.0.0',
key_0=SetActionV1(
version='1.0.0',
data=RefComponent(ref='vars.0'),
payload='failure'
),
key_1=SetActionV1(
version='1.0.0',
data=RefComponent(ref='vars.0'),
payload='a'
),
key_2=SetActionV1(
version='1.0.0',
data=RefComponent(ref='vars.0'),
payload='b'
)
)
],
vars={'0': OutputData(path='result')}
)

expected_input = {
'image_a': JsonSpec(),
'image_b': JsonSpec(),
'text': JsonSpec(),
}

expected_output = {
'result': JsonSpec(),
'why': JsonSpec
}

assert expected_input, expected_output == get_input_and_output(tb_config)
assert expected_input, expected_output == get_input_and_output(tb_config.unstructure())
2 changes: 1 addition & 1 deletion tests/test_training.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def training_map():
'training_tasks_in_task_suite_count': 3,
'task_suites_required_to_pass': 5,
'retry_training_after_days': 1,
'inherited_instructions': 'text',
'inherited_instructions': True,
'metadata': {'testKey': ['testValue']},
'assignment_max_duration_seconds': 600,
'public_instructions': 'text'
Expand Down

0 comments on commit 1d244a6

Please sign in to comment.