Skip to content

Commit

Permalink
toloka-kit==0.1.8 release
Browse files Browse the repository at this point in the history
toloka-kit==0.1.8 release
  • Loading branch information
Losik authored Jun 28, 2021
2 parents c219f9d + 281cf98 commit 7694634
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 59 deletions.
12 changes: 12 additions & 0 deletions .devexp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"strict": true,
"notification": "email",
"static_members": [
"losev",
"sinosov",
"tulinev",
"vlad-mois"
],
"approve_count": 1,
"total_reviewers": 1
}
7 changes: 7 additions & 0 deletions CHANGELOG.rst → CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
0.1.8
-------------------
* Added `get_aggregated_solutions` method
* Supported webhooks related methods
* Tracebacks in expanded methods do not show confusing TypeError as an original exception


0.1.7
-------------------
* Fixed error on ARRAY_JSON typed fields specs structuring
Expand Down
18 changes: 5 additions & 13 deletions examples/SQUAD2.0/SQUAD2.0_processing.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -962,25 +962,17 @@
" return task_to_assignment\n",
"\n",
"\n",
"def get_aggregation_results():\n",
"def get_aggregation_results(pool_id):\n",
" print('Start aggregation in the verification pool')\n",
" aggregation_operation = toloka_client.aggregate_solutions_by_pool(\n",
" type='DAWID_SKENE',\n",
" pool_id=verification_pool.id,\n",
" pool_id=pool_id,\n",
" fields=[toloka.aggregation.PoolAggregatedSolutionRequest.Field(name='is_correct')]\n",
" )\n",
" aggregation_operation = toloka_client.wait_operation(aggregation_operation)\n",
" print('Results aggregated')\n",
"\n",
" aggregation_result = toloka_client.find_aggregated_solutions(aggregation_operation.id)\n",
" verification_results = aggregation_result.items\n",
" while aggregation_result.has_more:\n",
" aggregation_result = toloka_client.find_aggregated_solutions(\n",
" aggregation_operation.id,\n",
" task_id_gt=aggregation_result.items[len(aggregation_result.items) - 1].task_id,\n",
" )\n",
" verification_results = verification_results + aggregation_result.items\n",
" return verification_results\n",
" return list(toloka_client.get_aggregated_solutions(aggregation_operation.id))\n",
"\n",
"\n",
"def set_answers_status(verification_results):\n",
Expand Down Expand Up @@ -1053,7 +1045,7 @@
" print(f'Verification pool {verification_pool.id} is finally closed!')\n",
"\n",
" # Aggregation operation\n",
" verification_results = get_aggregation_results()\n",
" verification_results = get_aggregation_results(verification_pool.id)\n",
" # Reject or accept tasks in the segmentation pool\n",
" set_answers_status(verification_results)\n",
"\n",
Expand Down Expand Up @@ -1172,4 +1164,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
26 changes: 7 additions & 19 deletions examples/image_segmentation/image_segmentation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -843,12 +843,12 @@
"cell_type": "code",
"metadata": {},
"source": [
"def get_aggregation_results():\n",
"def get_aggregation_results(pool_id, skill_id):\n",
" print('Start aggregation in the verification pool')\n",
" aggregation_operation = toloka_client.aggregate_solutions_by_pool(\n",
" type=toloka.aggregation.AggregatedSolutionType.WEIGHTED_DYNAMIC_OVERLAP,\n",
" pool_id=verification_pool.id, # Aggregate in this pool\n",
" answer_weight_skill_id=verification_skill.id, # Aggregate by this skill\n",
" pool_id=pool_id, # Aggregate in this pool\n",
" answer_weight_skill_id=skill_id, # Aggregate by this skill\n",
" fields=[toloka.aggregation.PoolAggregatedSolutionRequest.Field(name='result')] # Aggregate this field\n",
" )\n",
"\n",
Expand All @@ -857,19 +857,7 @@
" print('Results aggregated')\n",
"\n",
" # Get aggregated results\n",
" # Set a limit to show how to iterate over aggregation results\n",
" aggregation_result = toloka_client.find_aggregated_solutions(aggregation_operation.id, limit=5)\n",
" verification_results = aggregation_result.items\n",
" # If we have more results, let's get them\n",
" while aggregation_result.has_more:\n",
" aggregation_result = toloka_client.find_aggregated_solutions(\n",
" aggregation_operation.id,\n",
" # We have to establish which id we want to get results from (or else we'll loop back)\n",
" # This is usually the last item id in the previous request\n",
" task_id_gt=aggregation_result.items[len(aggregation_result.items) - 1].task_id,\n",
" )\n",
" verification_results = verification_results + aggregation_result.items\n",
" return verification_results\n",
" return list(toloka_client.get_aggregated_solutions(aggregation_operation.id))\n",
"\n",
"\n",
"def set_segmentation_status(verification_results):\n",
Expand All @@ -890,7 +878,7 @@
"\n",
"\n",
"# Aggregation operation\n",
"verification_results = get_aggregation_results()\n",
"verification_results = get_aggregation_results(verification_pool.id, verification_skill.id)\n",
"# Reject or accept tasks in the segmentation pool\n",
"set_segmentation_status(verification_results)"
],
Expand Down Expand Up @@ -931,7 +919,7 @@
" print(f'Verification pool {verification_pool.id} is finally closed!')\n",
"\n",
" # Aggregation operation\n",
" verification_results = get_aggregation_results()\n",
" verification_results = get_aggregation_results(verification_pool.id, verification_skill.id)\n",
" # Reject or accept tasks in the segmentation pool\n",
" set_segmentation_status(verification_results)\n",
"\n",
Expand Down Expand Up @@ -1026,4 +1014,4 @@
]
}
]
}
}
49 changes: 38 additions & 11 deletions src/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,22 @@
'Pool',
'Project',
]
import datetime
from decimal import Decimal
import time
from enum import Enum, unique
from typing import List, Optional, Union, BinaryIO, Tuple, Generator
import pandas as pd

import attr

import datetime
import functools
import io
import logging
import pandas as pd
import requests
import time
import uuid

from decimal import Decimal
from enum import Enum, unique
from requests.adapters import HTTPAdapter
from typing import BinaryIO, Generator, List, Optional, Tuple, Union
from urllib3.util.retry import Retry
import uuid

from . import actions # noqa: F401
from . import aggregation
Expand Down Expand Up @@ -312,7 +313,8 @@ def aggregate_solutions_by_task(self, request: aggregation.WeightedDynamicOverla
def find_aggregated_solutions(self, operation_id: str, request: search_requests.AggregatedSolutionSearchRequest,
sort: Union[List[str], search_requests.AggregatedSolutionSortItems, None] = None,
limit: Optional[int] = None) -> search_results.AggregatedSolutionSearchResult:
"""Gets aggregated responses after the AggregatedSolutionOperation completes
"""Gets aggregated responses after the AggregatedSolutionOperation completes.
It is better to use the "get_aggregated_solutions" method, that allows to iterate through all results.
Note: In all aggregation purposes we are strongly recommending using our crowd-kit library, that have more aggregation
methods and can perform on your computers: https://github.com/Toloka/crowd-kit
Expand Down Expand Up @@ -347,6 +349,31 @@ def find_aggregated_solutions(self, operation_id: str, request: search_requests.
response = self._search_request('get', f'/v1/aggregated-solutions/{operation_id}', request, sort, limit)
return structure(response, search_results.AggregatedSolutionSearchResult)

@expand('request')
def get_aggregated_solutions(self, operation_id: str, request: search_requests.AggregatedSolutionSearchRequest) -> Generator[AggregatedSolution, None, None]:
"""Finds all aggregated responses after the AggregatedSolutionOperation completes
Note: In all aggregation purposes we are strongly recommending using our crowd-kit library, that have more aggregation
methods and can perform on your computers: https://github.com/Toloka/crowd-kit
Args:
operation_id: From what aggregation operation you want to get results.
request: How to filter search results.
Yields:
AggregatedSolution: The next object corresponding to the request parameters.
Example:
How to get all aggregated solutions from pool.
>>> # run toloka_client.aggregate_solutions_by_pool and wait operation for closing.
>>> aggregation_results = list(toloka_client.get_aggregated_solutions(aggregation_operation.id))
>>> print(len(aggregation_results))
...
"""
find_function = functools.partial(self.find_aggregated_solutions, operation_id)
return self._find_all(find_function, request, sort_field='task_id')

# Assignments section

def accept_assignment(self, assignment_id: str, public_comment: str) -> Assignment:
Expand Down Expand Up @@ -2176,7 +2203,7 @@ def delete_user_skill(self, user_skill_id: str) -> None:
"""
self._raw_request('delete', f'/v1/user-skills/{user_skill_id}')

def create_webhook_subscriptions(self, subscriptions: List[WebhookSubscription]) -> batch_create_results.WebhookSubscriptionBatchCreateResult:
def upsert_webhook_subscriptions(self, subscriptions: List[WebhookSubscription]) -> batch_create_results.WebhookSubscriptionBatchCreateResult:
"""Creates (upsert) many webhook-subscriptions.
Args:
Expand All @@ -2192,7 +2219,7 @@ def create_webhook_subscriptions(self, subscriptions: List[WebhookSubscription])
Example:
How to create several subscriptions.
>>> created_result = toloka_client.create_webhook_subscriptions([
>>> created_result = toloka_client.upsert_webhook_subscriptions([
>>> {
>>> 'webhook_url': 'https://awesome-requester.com/toloka-webhook',
>>> 'event_type': toloka.webhook_subscription.WebhookSubscription.EventType.ASSIGNMENT_CREATED,
Expand Down
58 changes: 54 additions & 4 deletions src/client/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,7 @@ class TolokaClient:
"""
...

def create_webhook_subscriptions(self, subscriptions: List[WebhookSubscription]) -> WebhookSubscriptionBatchCreateResult:
def upsert_webhook_subscriptions(self, subscriptions: List[WebhookSubscription]) -> WebhookSubscriptionBatchCreateResult:
"""Creates (upsert) many webhook-subscriptions.
Args:
Expand All @@ -1136,7 +1136,7 @@ class TolokaClient:
Example:
How to create several subscriptions.
>>> created_result = toloka_client.create_webhook_subscriptions([
>>> created_result = toloka_client.upsert_webhook_subscriptions([
>>> {
>>> 'webhook_url': 'https://awesome-requester.com/toloka-webhook',
>>> 'event_type': toloka.webhook_subscription.WebhookSubscription.EventType.ASSIGNMENT_CREATED,
Expand Down Expand Up @@ -1197,7 +1197,8 @@ class TolokaClient:

@overload
def find_aggregated_solutions(self, operation_id: str, task_id_lt: Optional[str] = None, task_id_lte: Optional[str] = None, task_id_gt: Optional[str] = None, task_id_gte: Optional[str] = None, sort: Union[List[str], AggregatedSolutionSortItems, None] = None, limit: Optional[int] = None) -> AggregatedSolutionSearchResult:
"""Gets aggregated responses after the AggregatedSolutionOperation completes
"""Gets aggregated responses after the AggregatedSolutionOperation completes.
It is better to use the "get_aggregated_solutions" method, that allows to iterate through all results.
Note: In all aggregation purposes we are strongly recommending using our crowd-kit library, that have more aggregation
methods and can perform on your computers: https://github.com/Toloka/crowd-kit
Expand Down Expand Up @@ -1232,7 +1233,8 @@ class TolokaClient:

@overload
def find_aggregated_solutions(self, operation_id: str, request: AggregatedSolutionSearchRequest, sort: Union[List[str], AggregatedSolutionSortItems, None] = None, limit: Optional[int] = None) -> AggregatedSolutionSearchResult:
"""Gets aggregated responses after the AggregatedSolutionOperation completes
"""Gets aggregated responses after the AggregatedSolutionOperation completes.
It is better to use the "get_aggregated_solutions" method, that allows to iterate through all results.
Note: In all aggregation purposes we are strongly recommending using our crowd-kit library, that have more aggregation
methods and can perform on your computers: https://github.com/Toloka/crowd-kit
Expand Down Expand Up @@ -1265,6 +1267,54 @@ class TolokaClient:
"""
...

@overload
def get_aggregated_solutions(self, operation_id: str, task_id_lt: Optional[str] = None, task_id_lte: Optional[str] = None, task_id_gt: Optional[str] = None, task_id_gte: Optional[str] = None) -> Generator[AggregatedSolution, None, None]:
"""Finds all aggregated responses after the AggregatedSolutionOperation completes
Note: In all aggregation purposes we are strongly recommending using our crowd-kit library, that have more aggregation
methods and can perform on your computers: https://github.com/Toloka/crowd-kit
Args:
operation_id: From what aggregation operation you want to get results.
request: How to filter search results.
Yields:
AggregatedSolution: The next object corresponding to the request parameters.
Example:
How to get all aggregated solutions from pool.
>>> # run toloka_client.aggregate_solutions_by_pool and wait operation for closing.
>>> aggregation_results = list(toloka_client.get_aggregated_solutions(aggregation_operation.id))
>>> print(len(aggregation_results))
...
"""
...

@overload
def get_aggregated_solutions(self, operation_id: str, request: AggregatedSolutionSearchRequest) -> Generator[AggregatedSolution, None, None]:
"""Finds all aggregated responses after the AggregatedSolutionOperation completes
Note: In all aggregation purposes we are strongly recommending using our crowd-kit library, that have more aggregation
methods and can perform on your computers: https://github.com/Toloka/crowd-kit
Args:
operation_id: From what aggregation operation you want to get results.
request: How to filter search results.
Yields:
AggregatedSolution: The next object corresponding to the request parameters.
Example:
How to get all aggregated solutions from pool.
>>> # run toloka_client.aggregate_solutions_by_pool and wait operation for closing.
>>> aggregation_results = list(toloka_client.get_aggregated_solutions(aggregation_operation.id))
>>> print(len(aggregation_results))
...
"""
...

@overload
def find_assignments(self, status: Union[str, Assignment.Status, List[Union[str, Assignment.Status]]] = None, task_id: Optional[str] = None, task_suite_id: Optional[str] = None, pool_id: Optional[str] = None, user_id: Optional[str] = None, id_lt: Optional[str] = None, id_lte: Optional[str] = None, id_gt: Optional[str] = None, id_gte: Optional[str] = None, created_lt: Optional[datetime] = None, created_lte: Optional[datetime] = None, created_gt: Optional[datetime] = None, created_gte: Optional[datetime] = None, submitted_lt: Optional[datetime] = None, submitted_lte: Optional[datetime] = None, submitted_gt: Optional[datetime] = None, submitted_gte: Optional[datetime] = None, sort: Union[List[str], AssignmentSortItems, None] = None, limit: Optional[int] = None) -> AssignmentSearchResult:
"""Finds all assignments that match certain rules
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.7'
__version__ = '0.1.8'
__license__ = 'Apache 2.0'
10 changes: 10 additions & 0 deletions src/client/project/template_builder/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ class HotkeysPluginV1(BasePluginV1, spec_value=ComponentType.PLUGIN_HOTKEYS):
Attributes:
key_ + [a-z|0-9|up|down]: An action that is triggered when you press the specified keyboard key. The keyboard
shortcut is set in the key, and the action is specified in the value
Example:
How to create hotkeys for classification buttons.
>>> hot_keys_plugin = tb.HotkeysPluginV1(
>>> key_1=tb.SetActionV1(data=tb.OutputData(path='result'), payload='cat'),
>>> key_2=tb.SetActionV1(data=tb.OutputData(path='result'), payload='dog'),
>>> key_3=tb.SetActionV1(data=tb.OutputData(path='result'), payload='other'),
>>> )
...
"""

key_a: base_component_or(Any) = attribute(default=None, origin='a')
Expand Down
10 changes: 10 additions & 0 deletions src/client/project/template_builder/plugins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ class HotkeysPluginV1(BasePluginV1):
Attributes:
key_ + [a-z|0-9|up|down]: An action that is triggered when you press the specified keyboard key. The keyboard
shortcut is set in the key, and the action is specified in the value
Example:
How to create hotkeys for classification buttons.
>>> hot_keys_plugin = tb.HotkeysPluginV1(
>>> key_1=tb.SetActionV1(data=tb.OutputData(path='result'), payload='cat'),
>>> key_2=tb.SetActionV1(data=tb.OutputData(path='result'), payload='dog'),
>>> key_3=tb.SetActionV1(data=tb.OutputData(path='result'), payload='other'),
>>> )
...
"""

def __init__(self, *, version: Optional[str] = '1.0.0', key_a: Optional[Any] = None, key_b: Optional[Any] = None, key_c: Optional[Any] = None, key_d: Optional[Any] = None, key_e: Optional[Any] = None, key_f: Optional[Any] = None, key_g: Optional[Any] = None, key_h: Optional[Any] = None, key_i: Optional[Any] = None, key_j: Optional[Any] = None, key_k: Optional[Any] = None, key_l: Optional[Any] = None, key_m: Optional[Any] = None, key_n: Optional[Any] = None, key_o: Optional[Any] = None, key_p: Optional[Any] = None, key_q: Optional[Any] = None, key_r: Optional[Any] = None, key_s: Optional[Any] = None, key_t: Optional[Any] = None, key_u: Optional[Any] = None, key_v: Optional[Any] = None, key_w: Optional[Any] = None, key_x: Optional[Any] = None, key_y: Optional[Any] = None, key_z: Optional[Any] = None, key_0: Optional[Any] = None, key_1: Optional[Any] = None, key_2: Optional[Any] = None, key_3: Optional[Any] = None, key_4: Optional[Any] = None, key_5: Optional[Any] = None, key_6: Optional[Any] = None, key_7: Optional[Any] = None, key_8: Optional[Any] = None, key_9: Optional[Any] = None, key_up: Optional[Any] = None, key_down: Optional[Any] = None) -> None:
Expand Down
1 change: 1 addition & 0 deletions src/client/webhook_subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class EventType(Enum):
webhook_url: str
event_type: EventType
pool_id: str
secret_key: str

# Readonly
id: str
Expand Down
3 changes: 2 additions & 1 deletion src/client/webhook_subscription.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class WebhookSubscription(BaseTolokaObject):
ASSIGNMENT_APPROVED = 'ASSIGNMENT_APPROVED'
ASSIGNMENT_REJECTED = 'ASSIGNMENT_REJECTED'

def __init__(self, *, webhook_url: Optional[str] = None, event_type: Optional[EventType] = None, pool_id: Optional[str] = None, id: Optional[str] = None, created: Optional[datetime] = None) -> None:
def __init__(self, *, webhook_url: Optional[str] = None, event_type: Optional[EventType] = None, pool_id: Optional[str] = None, secret_key: Optional[str] = None, id: Optional[str] = None, created: Optional[datetime] = None) -> None:
"""Method generated by attrs for class WebhookSubscription.
"""
...
Expand All @@ -50,5 +50,6 @@ class WebhookSubscription(BaseTolokaObject):
webhook_url: Optional[str]
event_type: Optional[EventType]
pool_id: Optional[str]
secret_key: Optional[str]
id: Optional[str]
created: Optional[datetime]
Loading

0 comments on commit 7694634

Please sign in to comment.