diff --git a/apps/assisted_tagging/admin.py b/apps/assisted_tagging/admin.py index 846f6b4061..8bcc2de9f4 100644 --- a/apps/assisted_tagging/admin.py +++ b/apps/assisted_tagging/admin.py @@ -1 +1,52 @@ # Register your models here. +from admin_auto_filters.filters import AutocompleteFilterFactory +from django.contrib import admin + +from assisted_tagging.models import AssistedTaggingModelPredictionTag, AssistedTaggingPrediction, DraftEntry +from deep.admin import VersionAdmin + + +@admin.register(DraftEntry) +class DraftEntryAdmin(VersionAdmin): + search_fields = ['lead'] + list_display = [ + 'lead', + 'prediction_status', + ] + list_filter = ( + AutocompleteFilterFactory('Lead', 'lead'), + AutocompleteFilterFactory('Project', 'project'), + 'type' + ) + + autocomplete_fields = ('project', 'lead', 'related_geoareas',) + + +@admin.register(AssistedTaggingPrediction) +class AssistedTaggingPredictionAdmin(VersionAdmin): + search_fields = ['draft_entry'] + list_display = [ + "data_type", + "draft_entry", + "value", + "is_selected", + "tag", + ] + list_filter = ( + AutocompleteFilterFactory('DraftEntry', 'draft_entry'), + + ) + # NOTE: Skipping model_version. Only few of them exists + autocomplete_fields = ('draft_entry', 'category', 'tag') + + +@admin.register(AssistedTaggingModelPredictionTag) +class AssistedTaggingModelPredictionTagAdmin(VersionAdmin): + search_fields = ['parent_tag'] + list_display = [ + 'name', + 'is_category', + 'tag_id', + 'parent_tag', + ] + autocomplete_fields = ('parent_tag',) diff --git a/apps/assisted_tagging/enums.py b/apps/assisted_tagging/enums.py index 996c7629e9..3301924fb3 100644 --- a/apps/assisted_tagging/enums.py +++ b/apps/assisted_tagging/enums.py @@ -14,12 +14,16 @@ DraftEntry.PredictionStatus, name='DraftEntryPredictionStatusEnum') AssistedTaggingPredictionDataTypeEnum = convert_enum_to_graphene_enum( AssistedTaggingPrediction.DataType, name='AssistedTaggingPredictionDataTypeEnum') +DraftEntryTypeEnum = convert_enum_to_graphene_enum( + DraftEntry.Type, name="DraftEntryTypeEnum" +) enum_map = { get_enum_name_from_django_field(field): enum for field, enum in ( (DraftEntry.prediction_status, DraftEntryPredictionStatusEnum), (AssistedTaggingPrediction.data_type, AssistedTaggingPredictionDataTypeEnum), + (DraftEntry.type, DraftEntryTypeEnum), ) } diff --git a/apps/assisted_tagging/filters.py b/apps/assisted_tagging/filters.py index 792d600548..0a32ef768b 100644 --- a/apps/assisted_tagging/filters.py +++ b/apps/assisted_tagging/filters.py @@ -1 +1,17 @@ -# +import django_filters + +from .models import DraftEntry +from utils.graphene.filters import IDFilter, MultipleInputFilter +from .enums import ( + DraftEntryTypeEnum +) + + +class DraftEntryFilterSet(django_filters.FilterSet): + lead = IDFilter(field_name='lead') + draft_entry_types = MultipleInputFilter(DraftEntryTypeEnum, field_name='type') + is_discarded = django_filters.BooleanFilter() + + class Meta: + model = DraftEntry + fields = () diff --git a/apps/assisted_tagging/migrations/0011_draftentry_draft_entry_type.py b/apps/assisted_tagging/migrations/0011_draftentry_draft_entry_type.py new file mode 100644 index 0000000000..0fec29e96d --- /dev/null +++ b/apps/assisted_tagging/migrations/0011_draftentry_draft_entry_type.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.17 on 2023-11-06 10:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('assisted_tagging', '0010_draftentry_related_geoareas'), + ] + + operations = [ + migrations.AddField( + model_name='draftentry', + name='draft_entry_type', + field=models.SmallIntegerField(choices=[(0, 'Auto Extraction'), (1, 'Manual Extraction')], default=1), + ), + ] diff --git a/apps/assisted_tagging/migrations/0011_draftentry_draft_entry_type_squashed_0013_rename_draft_entry_type_draftentry_type.py b/apps/assisted_tagging/migrations/0011_draftentry_draft_entry_type_squashed_0013_rename_draft_entry_type_draftentry_type.py new file mode 100644 index 0000000000..e40d88d2d3 --- /dev/null +++ b/apps/assisted_tagging/migrations/0011_draftentry_draft_entry_type_squashed_0013_rename_draft_entry_type_draftentry_type.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.17 on 2023-12-21 11:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + replaces = [('assisted_tagging', '0011_draftentry_draft_entry_type'), ('assisted_tagging', '0012_draftentry_is_discarded'), ('assisted_tagging', '0013_rename_draft_entry_type_draftentry_type')] + + dependencies = [ + ('assisted_tagging', '0010_draftentry_related_geoareas'), + ] + + operations = [ + migrations.AddField( + model_name='draftentry', + name='is_discarded', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='draftentry', + name='type', + field=models.SmallIntegerField(choices=[(0, 'Auto Extraction'), (1, 'Manual Extraction')], default=1), + ), + ] diff --git a/apps/assisted_tagging/migrations/0012_draftentry_is_discarded.py b/apps/assisted_tagging/migrations/0012_draftentry_is_discarded.py new file mode 100644 index 0000000000..63746219e8 --- /dev/null +++ b/apps/assisted_tagging/migrations/0012_draftentry_is_discarded.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.17 on 2023-12-11 05:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('assisted_tagging', '0011_draftentry_draft_entry_type'), + ] + + operations = [ + migrations.AddField( + model_name='draftentry', + name='is_discarded', + field=models.BooleanField(default=False), + ), + ] diff --git a/apps/assisted_tagging/migrations/0013_rename_draft_entry_type_draftentry_type.py b/apps/assisted_tagging/migrations/0013_rename_draft_entry_type_draftentry_type.py new file mode 100644 index 0000000000..9d479d4355 --- /dev/null +++ b/apps/assisted_tagging/migrations/0013_rename_draft_entry_type_draftentry_type.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.17 on 2023-12-20 11:34 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('assisted_tagging', '0012_draftentry_is_discarded'), + ] + + operations = [ + migrations.RenameField( + model_name='draftentry', + old_name='draft_entry_type', + new_name='type', + ), + ] diff --git a/apps/assisted_tagging/models.py b/apps/assisted_tagging/models.py index 2464ab5b0e..1c7af87028 100644 --- a/apps/assisted_tagging/models.py +++ b/apps/assisted_tagging/models.py @@ -90,6 +90,10 @@ class PredictionStatus(models.IntegerChoices): DONE = 2, 'Done' SEND_FAILED = 3, 'Send Failed' + class Type(models.IntegerChoices): + AUTO = 0, 'Auto Extraction' # NLP defiend extraction text + MANUAL = 1, 'Manual Extraction' # manual defined extraction text + project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='+') lead = models.ForeignKey(Lead, on_delete=models.CASCADE, related_name='+') excerpt = models.TextField() @@ -98,6 +102,11 @@ class PredictionStatus(models.IntegerChoices): prediction_received_at = models.DateTimeField(null=True, blank=True) # Additional attribues related_geoareas = models.ManyToManyField(GeoArea, blank=True) + type = models.SmallIntegerField(choices=Type.choices, default=Type.MANUAL) + is_discarded = models.BooleanField(default=False) + + def __str__(self): + return f'{self.id}' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -176,7 +185,7 @@ class DataType(models.IntegerChoices): id: int def __str__(self): - return self.id + return str(self.id) class WrongPredictionReview(UserResource): diff --git a/apps/assisted_tagging/mutation.py b/apps/assisted_tagging/mutation.py index f47c80952b..abfd134c37 100644 --- a/apps/assisted_tagging/mutation.py +++ b/apps/assisted_tagging/mutation.py @@ -4,6 +4,7 @@ generate_input_type_for_serializer, PsGrapheneMutation, PsDeleteMutation, + mutation_is_not_valid ) from deep.permissions import ProjectPermissions as PP @@ -21,6 +22,8 @@ DraftEntryGqlSerializer, WrongPredictionReviewGqlSerializer, MissingPredictionReviewGqlSerializer, + TriggerDraftEntryGqlSerializer, + UpdateDraftEntrySerializer ) @@ -39,6 +42,16 @@ serializer_class=MissingPredictionReviewGqlSerializer, ) +TriggerAutoDraftEntryInputType = generate_input_type_for_serializer( + "TriggerAutoDraftEntryInputType", + serializer_class=TriggerDraftEntryGqlSerializer +) + +UpdateDraftEntryInputType = generate_input_type_for_serializer( + "UpdateDraftEntryInputType", + serializer_class=UpdateDraftEntrySerializer +) + class CreateDraftEntry(PsGrapheneMutation): class Arguments: @@ -96,6 +109,35 @@ def filter_queryset(cls, qs, info): created_by=info.context.user, ) +# auto draft_entry_create + + +class TriggerAutoDraftEntry(PsGrapheneMutation): + class Arguments: + data = TriggerAutoDraftEntryInputType(required=True) + model = DraftEntry + serializer_class = TriggerDraftEntryGqlSerializer + permissions = [PP.Permission.CREATE_ENTRY] + + @classmethod + def perform_mutate(cls, root, info, **kwargs): + data = kwargs['data'] + serializer = cls.serializer_class(data=data, context={'request': info.context.request}) + if errors := mutation_is_not_valid(serializer): + return cls(errors=errors, ok=False) + serializer.save() + return cls(errors=None, ok=True) + + +class UpdateDraftEntry(PsGrapheneMutation): + class Arguments: + data = UpdateDraftEntryInputType(required=True) + id = graphene.ID(required=True) + model = DraftEntry + serializer_class = UpdateDraftEntrySerializer + result = graphene.Field(DraftEntryType) + permissions = [PP.Permission.CREATE_ENTRY] + class AssistedTaggingMutationType(graphene.ObjectType): draft_entry_create = CreateDraftEntry.Field() @@ -103,3 +145,5 @@ class AssistedTaggingMutationType(graphene.ObjectType): wrong_prediction_review_create = CreateWrongPredictionReview.Field() missing_prediction_review_delete = DeleteMissingPredictionReview.Field() wrong_prediction_review_delete = DeleteWrongPredictionReview.Field() + trigger_auto_draft_entry = TriggerAutoDraftEntry.Field() + update_draft_entry = UpdateDraftEntry.Field() diff --git a/apps/assisted_tagging/schema.py b/apps/assisted_tagging/schema.py index f6ae0f23b8..6cc3718637 100644 --- a/apps/assisted_tagging/schema.py +++ b/apps/assisted_tagging/schema.py @@ -2,6 +2,7 @@ from graphene_django import DjangoObjectType from graphene_django_extras import DjangoObjectField from django.db.models import Prefetch +from assisted_tagging.filters import DraftEntryFilterSet from utils.graphene.enums import EnumDescription from user_resource.schema import UserResourceMixin @@ -11,6 +12,9 @@ ProjectGeoAreaType, get_geo_area_queryset_for_project_geo_area_type, ) +from utils.graphene.fields import DjangoPaginatedListObjectField +from utils.graphene.pagination import NoOrderingPageGraphqlPagination +from utils.graphene.types import CustomDjangoListObjectType from .models import ( DraftEntry, AssistedTaggingModel, @@ -96,10 +100,31 @@ def resolve_prediction_tags(root, info, **kwargs): # -- Project Level -def get_draft_entry_qs(info): +def get_draft_entry_qs(info): # TODO use dataloder qs = DraftEntry.objects.filter(project=info.context.active_project) if PP.check_permission(info, PP.Permission.VIEW_ENTRY): - return qs + return qs.prefetch_related( + Prefetch( + 'predictions', + queryset=AssistedTaggingPrediction.objects.filter(is_selected=True).order_by('id'), + ), + Prefetch( + 'related_geoareas', + queryset=get_geo_area_queryset_for_project_geo_area_type().order_by('id'), + ), + 'predictions__model_version', + 'predictions__model_version__model', + 'predictions__wrong_prediction_reviews', + 'missing_prediction_reviews', + 'related_geoareas', + ) + return qs.none() + + +def get_draft_entry_with_filter_qs(info, filters): + qs = DraftEntry.objects.filter(project=info.context.active_project) + if PP.check_permission(info, PP.Permission.VIEW_ENTRY): + return DraftEntryFilterSet(queryset=qs, data=filters).qs return qs.none() @@ -178,22 +203,8 @@ class Meta: ) @staticmethod - def get_custom_queryset(queryset, info, **kwargs): - return get_draft_entry_qs(info).prefetch_related( - Prefetch( - 'predictions', - queryset=AssistedTaggingPrediction.objects.order_by('id'), - ), - Prefetch( - 'related_geoareas', - queryset=get_geo_area_queryset_for_project_geo_area_type().order_by('id'), - ), - 'predictions__model_version', - 'predictions__model_version__model', - 'predictions__wrong_prediction_reviews', - 'missing_prediction_reviews', - 'related_geoareas', - ) + def get_custom_queryset(root, info, **kwargs): + return get_draft_entry_qs(info) @staticmethod def resolve_predictions(root, info, **kwargs): @@ -205,9 +216,27 @@ def resolve_missing_prediction_reviews(root, info, **kwargs): @staticmethod def resolve_related_geoareas(root, info, **kwargs): - return root.related_geoareas.all() # NOTE: Prefetched by DraftEntry + return root.related_geoareas.all() # NOTE: Prefetched by DraftEntry + + +class DraftEntryListType(CustomDjangoListObjectType): + class Meta: + model = DraftEntry + filterset_class = DraftEntryFilterSet # This is attached to project type. + + class AssistedTaggingQueryType(graphene.ObjectType): draft_entry = DjangoObjectField(DraftEntryType) + draft_entries = DjangoPaginatedListObjectField( + DraftEntryListType, + pagination=NoOrderingPageGraphqlPagination( + page_size_query_param='pageSize', + ), + ) + + @staticmethod + def resolve_draft_entries(root, info, **_): + return get_draft_entry_qs(info) diff --git a/apps/assisted_tagging/serializers.py b/apps/assisted_tagging/serializers.py index 3dcdb4d82c..c6798ad070 100644 --- a/apps/assisted_tagging/serializers.py +++ b/apps/assisted_tagging/serializers.py @@ -1,6 +1,5 @@ from django.db import transaction from rest_framework import serializers - from user_resource.serializers import UserResourceSerializer, UserResourceCreatedMixin from deep.serializers import ProjectPropertySerializerMixin, TempClientIdMixin from analysis_framework.models import Widget @@ -11,44 +10,50 @@ PredictionTagAnalysisFrameworkWidgetMapping, WrongPredictionReview, ) -from .tasks import trigger_request_for_draft_entry_task +from lead.models import Lead +from .tasks import ( + trigger_request_for_draft_entry_task, + trigger_request_for_auto_draft_entry_task +) # ---------- Graphql --------------------------- -class DraftEntryGqlSerializer(ProjectPropertySerializerMixin, UserResourceCreatedMixin, serializers.ModelSerializer): - class Meta: - model = DraftEntry - fields = ( - 'lead', - 'excerpt', - ) - +class DraftEntryBaseSerializer(serializers.Serializer): def validate_lead(self, lead): if lead.project != self.project: raise serializers.ValidationError('Only lead from current project are allowed.') af = lead.project.analysis_framework if af is None or not af.assisted_tagging_enabled: raise serializers.ValidationError('Assisted tagging is disabled for the Framework used by this project.') - return lead - - def validate(self, data): - if self.instance and self.instance.created_by != self.context['request'].user: - raise serializers.ValidationError('Only reviewer can edit this review') - data['project'] = self.project if self.project.is_private: raise serializers.ValidationError('Assisted tagging is not available for private projects.') - return data + if lead.confidentiality in (Lead.Confidentiality.CONFIDENTIAL, Lead.Confidentiality.RESTRICTED): + raise serializers.ValidationError('Assisted tagging is not available for confidential or restricated leads') + return lead + + +class DraftEntryGqlSerializer( + ProjectPropertySerializerMixin, DraftEntryBaseSerializer, UserResourceCreatedMixin, serializers.ModelSerializer +): + class Meta: + model = DraftEntry + fields = ( + 'lead', + 'excerpt', + ) def create(self, data): # Use already existing draft entry if found + project = data['lead'].project already_existing_draft_entry = DraftEntry.get_existing_draft_entry( - data['project'], + project, data['lead'], data['excerpt'], ) if already_existing_draft_entry: return already_existing_draft_entry # Create new one and send trigger to deepl. + data['project'] = project instance = super().create(data) transaction.on_commit( lambda: trigger_request_for_draft_entry_task.delay(instance.pk) @@ -56,7 +61,7 @@ def create(self, data): return instance def update(self, *_): - raise Exception('Update not allowed') + raise Exception("Update is not allowed") class WrongPredictionReviewGqlSerializer(UserResourceSerializer, serializers.ModelSerializer): @@ -127,3 +132,53 @@ def validate(self, data): association='Association is required for this widget.' )) return data + + +class TriggerDraftEntryGqlSerializer( + DraftEntryBaseSerializer, + ProjectPropertySerializerMixin, + UserResourceCreatedMixin, + serializers.ModelSerializer, +): + class Meta: + model = DraftEntry + fields = ( + 'lead', + ) + + def create(self, data): + lead = data['lead'] + if lead.leadpreview.text_extraction_id is None: + raise serializers.DjangoValidationError("Assisted tagging is not available in old lead") + if lead.auto_entry_extraction_status == Lead.AutoExtractionStatus.SUCCESS: + raise serializers.DjangoValidationError("Already Triggered") + if not lead.leadpreview.text_extract: + raise serializers.DjangoValidationError('Simplifed Text is empty') + draft_entry_qs = DraftEntry.objects.filter(lead=lead, type=DraftEntry.Type.AUTO) + if draft_entry_qs.exists(): + raise serializers.DjangoValidationError('Draft entry already exists') + # Use already existing draft entry if found + # Create new one and send trigger to deepl + lead.auto_entry_extraction_status = Lead.AutoExtractionStatus.PENDING + lead.save(update_fields=['auto_entry_extraction_status']) + transaction.on_commit( + lambda: trigger_request_for_auto_draft_entry_task.delay(lead.id) + ) + return True + + def update(self, instance, validate_data): + raise Exception("updated is not allowed") + + +class UpdateDraftEntrySerializer( + DraftEntryBaseSerializer, ProjectPropertySerializerMixin, UserResourceSerializer, serializers.ModelSerializer +): + class Meta: + model = DraftEntry + fields = ( + 'lead', + 'is_discarded', + ) + + def create(self, _): + raise Exception("Create is not Allowed") diff --git a/apps/assisted_tagging/tasks.py b/apps/assisted_tagging/tasks.py index e274a47334..3a7ca7fa46 100644 --- a/apps/assisted_tagging/tasks.py +++ b/apps/assisted_tagging/tasks.py @@ -2,10 +2,15 @@ import requests from celery import shared_task +from lead.models import Lead from utils.common import redis_lock from deep.deepl import DeeplServiceEndpoint -from deepl_integration.handlers import AssistedTaggingDraftEntryHandler +from deepl_integration.handlers import ( + AssistedTaggingDraftEntryHandler, + AutoAssistedTaggingDraftEntryHandler, + BaseHandler as DeepHandler +) from .models import ( DraftEntry, @@ -24,7 +29,8 @@ def _get_existing_tags_by_tagid(): tag.tag_id: tag # tag_id is from deepl for tag in AssistedTaggingModelPredictionTag.objects.all() } - response = requests.get(DeeplServiceEndpoint.ASSISTED_TAGGING_TAGS_ENDPOINT).json() + + response = requests.get(DeeplServiceEndpoint.ASSISTED_TAGGING_TAGS_ENDPOINT, headers=DeepHandler.REQUEST_HEADERS).json() existing_tags_by_tagid = _get_existing_tags_by_tagid() new_tags = [] @@ -92,6 +98,13 @@ def trigger_request_for_draft_entry_task(draft_entry_id): return AssistedTaggingDraftEntryHandler.send_trigger_request_to_extractor(draft_entry) +@shared_task +@redis_lock('trigger_request_for_auto_draft_entry_task_{0}', 60 * 60 * 0.5) +def trigger_request_for_auto_draft_entry_task(lead_id): + lead = Lead.objects.get(id=lead_id) + return AutoAssistedTaggingDraftEntryHandler.auto_trigger_request_to_extractor(lead) + + @shared_task @redis_lock('sync_tags_with_deepl_task', 60 * 60 * 0.5) def sync_tags_with_deepl_task(): diff --git a/apps/assisted_tagging/tests/snapshots/snap_test_query.py b/apps/assisted_tagging/tests/snapshots/snap_test_query.py index cd4f72eacd..c20c3ca0c4 100644 --- a/apps/assisted_tagging/tests/snapshots/snap_test_query.py +++ b/apps/assisted_tagging/tests/snapshots/snap_test_query.py @@ -8,37 +8,21 @@ snapshots = Snapshot() snapshots['AssistedTaggingCallbackApiTest::test_save_draft_entry final-current-model-stats'] = { - 'model_count': 3, - 'model_version_count': 3, + 'model_count': 1, + 'model_version_count': 1, 'model_versions': [ { 'model__model_id': 'all_tags_model', 'version': '1.0.0' - }, - { - 'model__model_id': 'geolocation', - 'version': '1.0.0' - }, - { - 'model__model_id': 'reliability', - 'version': '1.0.0' } ], 'models': [ { 'model_id': 'all_tags_model', 'name': 'all_tags_model' - }, - { - 'model_id': 'geolocation', - 'name': 'geolocation' - }, - { - 'model_id': 'reliability', - 'name': 'reliability' } ], - 'tag_count': 101, + 'tag_count': 45, 'tags': [ { 'is_deprecated': False, @@ -50,6 +34,11 @@ 'name': '101', 'tag_id': '101' }, + { + 'is_deprecated': False, + 'name': '102', + 'tag_id': '102' + }, { 'is_deprecated': False, 'name': '103', @@ -62,38 +51,43 @@ }, { 'is_deprecated': False, - 'name': '105', - 'tag_id': '105' + 'name': '2', + 'tag_id': '2' + }, + { + 'is_deprecated': False, + 'name': '204', + 'tag_id': '204' }, { 'is_deprecated': False, - 'name': '106', - 'tag_id': '106' + 'name': '209', + 'tag_id': '209' }, { 'is_deprecated': False, - 'name': '107', - 'tag_id': '107' + 'name': '214', + 'tag_id': '214' }, { 'is_deprecated': False, - 'name': '108', - 'tag_id': '108' + 'name': '216', + 'tag_id': '216' }, { 'is_deprecated': False, - 'name': '109', - 'tag_id': '109' + 'name': '217', + 'tag_id': '217' }, { 'is_deprecated': False, - 'name': '110', - 'tag_id': '110' + 'name': '218', + 'tag_id': '218' }, { 'is_deprecated': False, - 'name': '111', - 'tag_id': '111' + 'name': '219', + 'tag_id': '219' }, { 'is_deprecated': False, @@ -120,56 +114,6 @@ 'name': '304', 'tag_id': '304' }, - { - 'is_deprecated': False, - 'name': '305', - 'tag_id': '305' - }, - { - 'is_deprecated': False, - 'name': '306', - 'tag_id': '306' - }, - { - 'is_deprecated': False, - 'name': '307', - 'tag_id': '307' - }, - { - 'is_deprecated': False, - 'name': '308', - 'tag_id': '308' - }, - { - 'is_deprecated': False, - 'name': '309', - 'tag_id': '309' - }, - { - 'is_deprecated': False, - 'name': '310', - 'tag_id': '310' - }, - { - 'is_deprecated': False, - 'name': '311', - 'tag_id': '311' - }, - { - 'is_deprecated': False, - 'name': '312', - 'tag_id': '312' - }, - { - 'is_deprecated': False, - 'name': '313', - 'tag_id': '313' - }, - { - 'is_deprecated': False, - 'name': '314', - 'tag_id': '314' - }, { 'is_deprecated': False, 'name': '315', @@ -192,173 +136,48 @@ }, { 'is_deprecated': False, - 'name': '2', - 'tag_id': '2' - }, - { - 'is_deprecated': False, - 'name': '219', - 'tag_id': '219' - }, - { - 'is_deprecated': False, - 'name': '217', - 'tag_id': '217' - }, - { - 'is_deprecated': False, - 'name': '218', - 'tag_id': '218' - }, - { - 'is_deprecated': False, - 'name': '204', - 'tag_id': '204' - }, - { - 'is_deprecated': False, - 'name': '203', - 'tag_id': '203' - }, - { - 'is_deprecated': False, - 'name': '201', - 'tag_id': '201' - }, - { - 'is_deprecated': False, - 'name': '205', - 'tag_id': '205' - }, - { - 'is_deprecated': False, - 'name': '207', - 'tag_id': '207' - }, - { - 'is_deprecated': False, - 'name': '206', - 'tag_id': '206' - }, - { - 'is_deprecated': False, - 'name': '202', - 'tag_id': '202' - }, - { - 'is_deprecated': False, - 'name': '228', - 'tag_id': '228' - }, - { - 'is_deprecated': False, - 'name': '229', - 'tag_id': '229' - }, - { - 'is_deprecated': False, - 'name': '230', - 'tag_id': '230' - }, - { - 'is_deprecated': False, - 'name': '231', - 'tag_id': '231' - }, - { - 'is_deprecated': False, - 'name': '232', - 'tag_id': '232' - }, - { - 'is_deprecated': False, - 'name': '233', - 'tag_id': '233' - }, - { - 'is_deprecated': False, - 'name': '234', - 'tag_id': '234' - }, - { - 'is_deprecated': False, - 'name': '215', - 'tag_id': '215' - }, - { - 'is_deprecated': False, - 'name': '216', - 'tag_id': '216' - }, - { - 'is_deprecated': False, - 'name': '214', - 'tag_id': '214' - }, - { - 'is_deprecated': False, - 'name': '213', - 'tag_id': '213' - }, - { - 'is_deprecated': False, - 'name': '212', - 'tag_id': '212' - }, - { - 'is_deprecated': False, - 'name': '223', - 'tag_id': '223' - }, - { - 'is_deprecated': False, - 'name': '222', - 'tag_id': '222' - }, - { - 'is_deprecated': False, - 'name': '221', - 'tag_id': '221' + 'name': '4', + 'tag_id': '4' }, { 'is_deprecated': False, - 'name': '220', - 'tag_id': '220' + 'name': '401', + 'tag_id': '401' }, { 'is_deprecated': False, - 'name': '224', - 'tag_id': '224' + 'name': '402', + 'tag_id': '402' }, { 'is_deprecated': False, - 'name': '225', - 'tag_id': '225' + 'name': '407', + 'tag_id': '407' }, { 'is_deprecated': False, - 'name': '227', - 'tag_id': '227' + 'name': '408', + 'tag_id': '408' }, { 'is_deprecated': False, - 'name': '226', - 'tag_id': '226' + 'name': '412', + 'tag_id': '412' }, { 'is_deprecated': False, - 'name': '210', - 'tag_id': '210' + 'name': '5', + 'tag_id': '5' }, { 'is_deprecated': False, - 'name': '208', - 'tag_id': '208' + 'name': '501', + 'tag_id': '501' }, { 'is_deprecated': False, - 'name': '209', - 'tag_id': '209' + 'name': '502', + 'tag_id': '502' }, { 'is_deprecated': False, @@ -387,18 +206,13 @@ }, { 'is_deprecated': False, - 'name': '5', - 'tag_id': '5' - }, - { - 'is_deprecated': False, - 'name': '501', - 'tag_id': '501' + 'name': '7', + 'tag_id': '7' }, { 'is_deprecated': False, - 'name': '502', - 'tag_id': '502' + 'name': '701', + 'tag_id': '701' }, { 'is_deprecated': False, @@ -417,348 +231,106 @@ }, { 'is_deprecated': False, - 'name': '803', - 'tag_id': '803' + 'name': '9', + 'tag_id': '9' }, { 'is_deprecated': False, - 'name': '804', - 'tag_id': '804' + 'name': '904', + 'tag_id': '904' }, { 'is_deprecated': False, - 'name': '805', - 'tag_id': '805' + 'name': '905', + 'tag_id': '905' }, { 'is_deprecated': False, - 'name': '806', - 'tag_id': '806' - }, + 'name': '907', + 'tag_id': '907' + } + ] +} + +snapshots['AssistedTaggingCallbackApiTest::test_save_draft_entry final-current-prediction-stats'] = { + 'prediction_count': 72, + 'predictions': [ { - 'is_deprecated': False, - 'name': '4', - 'tag_id': '4' + 'category__tag_id': '1', + 'data_type': 1, + 'draft_entry__excerpt': 'sample excerpt 101', + 'is_selected': False, + 'model_version__model__model_id': 'all_tags_model', + 'prediction': GenericRepr("Decimal('0.00200000000000000004')"), + 'tag__tag_id': '101', + 'threshold': GenericRepr("Decimal('0.14000000000000001332')"), + 'value': '' }, { - 'is_deprecated': False, - 'name': '401', - 'tag_id': '401' + 'category__tag_id': '1', + 'data_type': 1, + 'draft_entry__excerpt': 'sample excerpt 101', + 'is_selected': True, + 'model_version__model__model_id': 'all_tags_model', + 'prediction': GenericRepr("Decimal('0.64800000000000002043')"), + 'tag__tag_id': '102', + 'threshold': GenericRepr("Decimal('0.17000000000000001221')"), + 'value': '' }, { - 'is_deprecated': False, - 'name': '402', - 'tag_id': '402' + 'category__tag_id': '1', + 'data_type': 1, + 'draft_entry__excerpt': 'sample excerpt 101', + 'is_selected': False, + 'model_version__model__model_id': 'all_tags_model', + 'prediction': GenericRepr("Decimal('0.02699999999999999969')"), + 'tag__tag_id': '103', + 'threshold': GenericRepr("Decimal('0.10000000000000000555')"), + 'value': '' }, { - 'is_deprecated': False, - 'name': '403', - 'tag_id': '403' + 'category__tag_id': '1', + 'data_type': 1, + 'draft_entry__excerpt': 'sample excerpt 101', + 'is_selected': False, + 'model_version__model__model_id': 'all_tags_model', + 'prediction': GenericRepr("Decimal('0.06199999999999999956')"), + 'tag__tag_id': '104', + 'threshold': GenericRepr("Decimal('0.14000000000000001332')"), + 'value': '' }, { - 'is_deprecated': False, - 'name': '404', - 'tag_id': '404' + 'category__tag_id': '2', + 'data_type': 1, + 'draft_entry__excerpt': 'sample excerpt 101', + 'is_selected': False, + 'model_version__model__model_id': 'all_tags_model', + 'prediction': GenericRepr("Decimal('0.00700000000000000015')"), + 'tag__tag_id': '204', + 'threshold': GenericRepr("Decimal('0.14000000000000001332')"), + 'value': '' }, { - 'is_deprecated': False, - 'name': '405', - 'tag_id': '405' + 'category__tag_id': '2', + 'data_type': 1, + 'draft_entry__excerpt': 'sample excerpt 101', + 'is_selected': True, + 'model_version__model__model_id': 'all_tags_model', + 'prediction': GenericRepr("Decimal('0.45800000000000001821')"), + 'tag__tag_id': '209', + 'threshold': GenericRepr("Decimal('0.05000000000000000278')"), + 'value': '' }, { - 'is_deprecated': False, - 'name': '406', - 'tag_id': '406' - }, - { - 'is_deprecated': False, - 'name': '407', - 'tag_id': '407' - }, - { - 'is_deprecated': False, - 'name': '408', - 'tag_id': '408' - }, - { - 'is_deprecated': False, - 'name': '409', - 'tag_id': '409' - }, - { - 'is_deprecated': False, - 'name': '410', - 'tag_id': '410' - }, - { - 'is_deprecated': False, - 'name': '411', - 'tag_id': '411' - }, - { - 'is_deprecated': False, - 'name': '412', - 'tag_id': '412' - }, - { - 'is_deprecated': False, - 'name': '9', - 'tag_id': '9' - }, - { - 'is_deprecated': False, - 'name': '904', - 'tag_id': '904' - }, - { - 'is_deprecated': False, - 'name': '905', - 'tag_id': '905' - }, - { - 'is_deprecated': False, - 'name': '902', - 'tag_id': '902' - }, - { - 'is_deprecated': False, - 'name': '903', - 'tag_id': '903' - }, - { - 'is_deprecated': False, - 'name': '906', - 'tag_id': '906' - }, - { - 'is_deprecated': False, - 'name': '907', - 'tag_id': '907' - }, - { - 'is_deprecated': False, - 'name': '10', - 'tag_id': '10' - }, - { - 'is_deprecated': False, - 'name': '1002', - 'tag_id': '1002' - } - ] -} - -snapshots['AssistedTaggingCallbackApiTest::test_save_draft_entry final-current-prediction-stats'] = { - 'prediction_count': 188, - 'predictions': [ - { - 'category__tag_id': None, - 'data_type': 0, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'geolocation', - 'prediction': None, - 'tag__tag_id': None, - 'threshold': None, - 'value': 'Nepal' - }, - { - 'category__tag_id': None, - 'data_type': 0, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'geolocation', - 'prediction': None, - 'tag__tag_id': None, - 'threshold': None, - 'value': 'Paris' - }, - { - 'category__tag_id': None, - 'data_type': 0, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, - 'model_version__model__model_id': 'geolocation', - 'prediction': None, - 'tag__tag_id': None, - 'threshold': None, - 'value': 'Nepal' - }, - { - 'category__tag_id': None, - 'data_type': 0, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, - 'model_version__model__model_id': 'geolocation', - 'prediction': None, - 'tag__tag_id': None, - 'threshold': None, - 'value': 'Paris' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00131315333064554660')"), - 'tag__tag_id': '101', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00301082416073135700')"), - 'tag__tag_id': '103', - 'threshold': GenericRepr("Decimal('0.46000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00256628797311956700')"), - 'tag__tag_id': '104', - 'threshold': GenericRepr("Decimal('0.48000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('2.67795523007710800000')"), - 'tag__tag_id': '105', - 'threshold': GenericRepr("Decimal('0.36000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01722483797685096000')"), - 'tag__tag_id': '106', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00367074832320213300')"), - 'tag__tag_id': '107', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00410134124816680450')"), - 'tag__tag_id': '108', - 'threshold': GenericRepr("Decimal('0.49000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.02810047168670029600')"), - 'tag__tag_id': '109', - 'threshold': GenericRepr("Decimal('0.58000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00356446807494475730')"), - 'tag__tag_id': '110', - 'threshold': GenericRepr("Decimal('0.42000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00885658950175879000')"), - 'tag__tag_id': '111', - 'threshold': GenericRepr("Decimal('0.53000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00161047546977275300')"), - 'tag__tag_id': '201', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00249261039939215920')"), - 'tag__tag_id': '202', - 'threshold': GenericRepr("Decimal('0.17000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00276056816801428800')"), - 'tag__tag_id': '203', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01951472795739466000')"), - 'tag__tag_id': '204', - 'threshold': GenericRepr("Decimal('0.49000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00284144639848701430')"), - 'tag__tag_id': '205', - 'threshold': GenericRepr("Decimal('0.31000000000000000000')"), - 'value': '' + 'category__tag_id': '2', + 'data_type': 1, + 'draft_entry__excerpt': 'sample excerpt 101', + 'is_selected': False, + 'model_version__model__model_id': 'all_tags_model', + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '214', + 'threshold': GenericRepr("Decimal('0.08999999999999999667')"), + 'value': '' }, { 'category__tag_id': '2', @@ -766,9 +338,9 @@ 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00284233643800358870')"), - 'tag__tag_id': '206', - 'threshold': GenericRepr("Decimal('0.44000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00300000000000000006')"), + 'tag__tag_id': '216', + 'threshold': GenericRepr("Decimal('0.13000000000000000444')"), 'value': '' }, { @@ -777,9 +349,9 @@ 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00300193069657931750')"), - 'tag__tag_id': '207', - 'threshold': GenericRepr("Decimal('0.30000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '217', + 'threshold': GenericRepr("Decimal('0.04000000000000000083')"), 'value': '' }, { @@ -788,9 +360,9 @@ 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00357941840775311000')"), - 'tag__tag_id': '208', - 'threshold': GenericRepr("Decimal('0.20000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00400000000000000008')"), + 'tag__tag_id': '218', + 'threshold': GenericRepr("Decimal('0.08999999999999999667')"), 'value': '' }, { @@ -799,1461 +371,405 @@ 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00632169711239197600')"), - 'tag__tag_id': '209', - 'threshold': GenericRepr("Decimal('0.17000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00300000000000000006')"), + 'tag__tag_id': '219', + 'threshold': GenericRepr("Decimal('0.13000000000000000444')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00697963860938730400')"), - 'tag__tag_id': '210', - 'threshold': GenericRepr("Decimal('0.23000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '301', + 'threshold': GenericRepr("Decimal('0.01000000000000000021')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01237871689035704300')"), - 'tag__tag_id': '212', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '302', + 'threshold': GenericRepr("Decimal('0.11000000000000000056')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00024467206802345010')"), - 'tag__tag_id': '213', - 'threshold': GenericRepr("Decimal('0.37000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.08300000000000000433')"), + 'tag__tag_id': '303', + 'threshold': GenericRepr("Decimal('0.38000000000000000444')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, + 'is_selected': True, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00036748812096354010')"), - 'tag__tag_id': '214', - 'threshold': GenericRepr("Decimal('0.29000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.08599999999999999312')"), + 'tag__tag_id': '304', + 'threshold': GenericRepr("Decimal('0.01000000000000000021')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00047817865331461160')"), - 'tag__tag_id': '215', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00300000000000000006')"), + 'tag__tag_id': '315', + 'threshold': GenericRepr("Decimal('0.45000000000000001110')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00696396781131625200')"), - 'tag__tag_id': '216', - 'threshold': GenericRepr("Decimal('0.25000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '316', + 'threshold': GenericRepr("Decimal('0.05999999999999999778')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00091310044249089870')"), - 'tag__tag_id': '217', - 'threshold': GenericRepr("Decimal('0.13000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00400000000000000008')"), + 'tag__tag_id': '317', + 'threshold': GenericRepr("Decimal('0.28000000000000002665')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00106291823053302660')"), - 'tag__tag_id': '218', - 'threshold': GenericRepr("Decimal('0.13000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '318', + 'threshold': GenericRepr("Decimal('0.13000000000000000444')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '4', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00187798162057463590')"), - 'tag__tag_id': '219', - 'threshold': GenericRepr("Decimal('0.28000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '401', + 'threshold': GenericRepr("Decimal('0.28999999999999998002')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '4', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01125925638038536600')"), - 'tag__tag_id': '220', - 'threshold': GenericRepr("Decimal('0.29000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '402', + 'threshold': GenericRepr("Decimal('0.45000000000000001110')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '4', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00166666776701611900')"), - 'tag__tag_id': '221', - 'threshold': GenericRepr("Decimal('0.19000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '407', + 'threshold': GenericRepr("Decimal('0.07000000000000000666')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '4', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00146527563629206270')"), - 'tag__tag_id': '222', - 'threshold': GenericRepr("Decimal('0.48000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '408', + 'threshold': GenericRepr("Decimal('0.11000000000000000056')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '4', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00115551359139065800')"), - 'tag__tag_id': '223', - 'threshold': GenericRepr("Decimal('0.47000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00758105556347540500')"), - 'tag__tag_id': '224', - 'threshold': GenericRepr("Decimal('0.21000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00033728324827582890')"), - 'tag__tag_id': '225', - 'threshold': GenericRepr("Decimal('0.15000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00077029108069837090')"), - 'tag__tag_id': '226', - 'threshold': GenericRepr("Decimal('0.18000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00090097592975426880')"), - 'tag__tag_id': '227', - 'threshold': GenericRepr("Decimal('0.18000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00497279979754239300')"), - 'tag__tag_id': '228', - 'threshold': GenericRepr("Decimal('0.80000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00032880847216941987')"), - 'tag__tag_id': '229', - 'threshold': GenericRepr("Decimal('0.39000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00116735643615233300')"), - 'tag__tag_id': '230', - 'threshold': GenericRepr("Decimal('0.81000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00244935224877624970')"), - 'tag__tag_id': '231', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00542857805671899200')"), - 'tag__tag_id': '232', - 'threshold': GenericRepr("Decimal('0.46000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00188743645513925370')"), - 'tag__tag_id': '233', - 'threshold': GenericRepr("Decimal('0.79000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00117788418989490570')"), - 'tag__tag_id': '234', - 'threshold': GenericRepr("Decimal('0.54000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00023104241032948875')"), - 'tag__tag_id': '301', - 'threshold': GenericRepr("Decimal('0.12000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00684022131126101400')"), - 'tag__tag_id': '302', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('1.51390548675291000000')"), - 'tag__tag_id': '303', - 'threshold': GenericRepr("Decimal('0.62000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00246191542828455570')"), - 'tag__tag_id': '304', - 'threshold': GenericRepr("Decimal('0.10000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.19748103480006374000')"), - 'tag__tag_id': '305', - 'threshold': GenericRepr("Decimal('0.43000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.13266879380965720000')"), - 'tag__tag_id': '306', - 'threshold': GenericRepr("Decimal('0.49000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00847395147300428900')"), - 'tag__tag_id': '307', - 'threshold': GenericRepr("Decimal('0.36000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01439434579677051900')"), - 'tag__tag_id': '308', - 'threshold': GenericRepr("Decimal('0.45000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00275349894147967100')"), - 'tag__tag_id': '309', - 'threshold': GenericRepr("Decimal('0.31000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.02261752535293742000')"), - 'tag__tag_id': '310', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00280699276022220930')"), - 'tag__tag_id': '311', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00353863737969235940')"), - 'tag__tag_id': '312', - 'threshold': GenericRepr("Decimal('0.33000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00474455507679118000')"), - 'tag__tag_id': '313', - 'threshold': GenericRepr("Decimal('0.45000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00243518249286959600')"), - 'tag__tag_id': '314', - 'threshold': GenericRepr("Decimal('0.24000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00498411668972535500')"), - 'tag__tag_id': '315', - 'threshold': GenericRepr("Decimal('0.55000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00342778279446065430')"), - 'tag__tag_id': '316', - 'threshold': GenericRepr("Decimal('0.15000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00183609818729261560')"), - 'tag__tag_id': '317', - 'threshold': GenericRepr("Decimal('0.30000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '3', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00765169737860560400')"), - 'tag__tag_id': '318', - 'threshold': GenericRepr("Decimal('0.25000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00020814205345232040')"), - 'tag__tag_id': '401', - 'threshold': GenericRepr("Decimal('0.25000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00299776057263129780')"), - 'tag__tag_id': '402', - 'threshold': GenericRepr("Decimal('0.58000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00299218206367056270')"), - 'tag__tag_id': '403', - 'threshold': GenericRepr("Decimal('0.14000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00241597760274695900')"), - 'tag__tag_id': '404', - 'threshold': GenericRepr("Decimal('0.48000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.02053049989999868700')"), - 'tag__tag_id': '405', - 'threshold': GenericRepr("Decimal('0.78000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00281014967745599850')"), - 'tag__tag_id': '406', - 'threshold': GenericRepr("Decimal('0.13000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00022843408415366598')"), - 'tag__tag_id': '407', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00943289911848003600')"), - 'tag__tag_id': '408', - 'threshold': GenericRepr("Decimal('0.59000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00091892403101415500')"), - 'tag__tag_id': '409', - 'threshold': GenericRepr("Decimal('0.56000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('2.03979988487399360000')"), - 'tag__tag_id': '410', - 'threshold': GenericRepr("Decimal('0.49000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00750677951145917200')"), - 'tag__tag_id': '411', - 'threshold': GenericRepr("Decimal('0.20000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '4', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00019092757914525768')"), - 'tag__tag_id': '412', - 'threshold': GenericRepr("Decimal('0.60000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '5', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('1.40336945023335200000')"), - 'tag__tag_id': '501', - 'threshold': GenericRepr("Decimal('0.71000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '5', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00778131599707359600')"), - 'tag__tag_id': '502', - 'threshold': GenericRepr("Decimal('0.44000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '6', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.04068703080217044000')"), - 'tag__tag_id': '601', - 'threshold': GenericRepr("Decimal('0.48000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '6', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.02458783670921217300')"), - 'tag__tag_id': '602', - 'threshold': GenericRepr("Decimal('0.44000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '6', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.04259871318936348000')"), - 'tag__tag_id': '603', - 'threshold': GenericRepr("Decimal('0.40000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '6', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00641449491997234200')"), - 'tag__tag_id': '604', - 'threshold': GenericRepr("Decimal('0.61000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00027582379877694870')"), - 'tag__tag_id': '801', - 'threshold': GenericRepr("Decimal('0.73000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00997524285181002000')"), - 'tag__tag_id': '802', - 'threshold': GenericRepr("Decimal('0.55000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00476177378710526100')"), - 'tag__tag_id': '803', - 'threshold': GenericRepr("Decimal('0.67000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00084620605533321700')"), - 'tag__tag_id': '804', - 'threshold': GenericRepr("Decimal('0.75000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00070480359681823760')"), - 'tag__tag_id': '805', - 'threshold': GenericRepr("Decimal('0.64000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00703320267416958500')"), - 'tag__tag_id': '806', - 'threshold': GenericRepr("Decimal('0.53000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '902', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '903', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '904', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '905', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '906', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '907', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00131315333064554660')"), - 'tag__tag_id': '101', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00301082416073135700')"), - 'tag__tag_id': '103', - 'threshold': GenericRepr("Decimal('0.46000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00256628797311956700')"), - 'tag__tag_id': '104', - 'threshold': GenericRepr("Decimal('0.48000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('2.67795523007710800000')"), - 'tag__tag_id': '105', - 'threshold': GenericRepr("Decimal('0.36000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01722483797685096000')"), - 'tag__tag_id': '106', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00367074832320213300')"), - 'tag__tag_id': '107', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00410134124816680450')"), - 'tag__tag_id': '108', - 'threshold': GenericRepr("Decimal('0.49000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.02810047168670029600')"), - 'tag__tag_id': '109', - 'threshold': GenericRepr("Decimal('0.58000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00356446807494475730')"), - 'tag__tag_id': '110', - 'threshold': GenericRepr("Decimal('0.42000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '1', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00885658950175879000')"), - 'tag__tag_id': '111', - 'threshold': GenericRepr("Decimal('0.53000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00161047546977275300')"), - 'tag__tag_id': '201', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00249261039939215920')"), - 'tag__tag_id': '202', - 'threshold': GenericRepr("Decimal('0.17000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00276056816801428800')"), - 'tag__tag_id': '203', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01951472795739466000')"), - 'tag__tag_id': '204', - 'threshold': GenericRepr("Decimal('0.49000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00284144639848701430')"), - 'tag__tag_id': '205', - 'threshold': GenericRepr("Decimal('0.31000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00284233643800358870')"), - 'tag__tag_id': '206', - 'threshold': GenericRepr("Decimal('0.44000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00300193069657931750')"), - 'tag__tag_id': '207', - 'threshold': GenericRepr("Decimal('0.30000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00357941840775311000')"), - 'tag__tag_id': '208', - 'threshold': GenericRepr("Decimal('0.20000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00632169711239197600')"), - 'tag__tag_id': '209', - 'threshold': GenericRepr("Decimal('0.17000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00697963860938730400')"), - 'tag__tag_id': '210', - 'threshold': GenericRepr("Decimal('0.23000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01237871689035704300')"), - 'tag__tag_id': '212', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00024467206802345010')"), - 'tag__tag_id': '213', - 'threshold': GenericRepr("Decimal('0.37000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00036748812096354010')"), - 'tag__tag_id': '214', - 'threshold': GenericRepr("Decimal('0.29000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00047817865331461160')"), - 'tag__tag_id': '215', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00696396781131625200')"), - 'tag__tag_id': '216', - 'threshold': GenericRepr("Decimal('0.25000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00091310044249089870')"), - 'tag__tag_id': '217', - 'threshold': GenericRepr("Decimal('0.13000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00106291823053302660')"), - 'tag__tag_id': '218', - 'threshold': GenericRepr("Decimal('0.13000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00187798162057463590')"), - 'tag__tag_id': '219', - 'threshold': GenericRepr("Decimal('0.28000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01125925638038536600')"), - 'tag__tag_id': '220', - 'threshold': GenericRepr("Decimal('0.29000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00166666776701611900')"), - 'tag__tag_id': '221', - 'threshold': GenericRepr("Decimal('0.19000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00146527563629206270')"), - 'tag__tag_id': '222', - 'threshold': GenericRepr("Decimal('0.48000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00115551359139065800')"), - 'tag__tag_id': '223', - 'threshold': GenericRepr("Decimal('0.47000000000000003000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00758105556347540500')"), - 'tag__tag_id': '224', - 'threshold': GenericRepr("Decimal('0.21000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00033728324827582890')"), - 'tag__tag_id': '225', - 'threshold': GenericRepr("Decimal('0.15000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00077029108069837090')"), - 'tag__tag_id': '226', - 'threshold': GenericRepr("Decimal('0.18000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00090097592975426880')"), - 'tag__tag_id': '227', - 'threshold': GenericRepr("Decimal('0.18000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '2', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00497279979754239300')"), - 'tag__tag_id': '228', - 'threshold': GenericRepr("Decimal('0.80000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '412', + 'threshold': GenericRepr("Decimal('0.35999999999999998668')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '5', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00032880847216941987')"), - 'tag__tag_id': '229', - 'threshold': GenericRepr("Decimal('0.39000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '501', + 'threshold': GenericRepr("Decimal('0.45000000000000001110')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '5', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00116735643615233300')"), - 'tag__tag_id': '230', - 'threshold': GenericRepr("Decimal('0.81000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '502', + 'threshold': GenericRepr("Decimal('0.47999999999999998224')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '6', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00244935224877624970')"), - 'tag__tag_id': '231', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '601', + 'threshold': GenericRepr("Decimal('0.05999999999999999778')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '6', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00542857805671899200')"), - 'tag__tag_id': '232', - 'threshold': GenericRepr("Decimal('0.46000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '602', + 'threshold': GenericRepr("Decimal('0.47999999999999998224')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '6', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00188743645513925370')"), - 'tag__tag_id': '233', - 'threshold': GenericRepr("Decimal('0.79000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.02199999999999999872')"), + 'tag__tag_id': '603', + 'threshold': GenericRepr("Decimal('0.34000000000000002442')"), 'value': '' }, { - 'category__tag_id': '2', + 'category__tag_id': '6', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00117788418989490570')"), - 'tag__tag_id': '234', - 'threshold': GenericRepr("Decimal('0.54000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '604', + 'threshold': GenericRepr("Decimal('0.16000000000000000333')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '7', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00023104241032948875')"), - 'tag__tag_id': '301', - 'threshold': GenericRepr("Decimal('0.12000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00800000000000000017')"), + 'tag__tag_id': '701', + 'threshold': GenericRepr("Decimal('0.27000000000000001776')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '8', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00684022131126101400')"), - 'tag__tag_id': '302', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '801', + 'threshold': GenericRepr("Decimal('0.66000000000000003109')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '8', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, + 'draft_entry__excerpt': 'sample excerpt 101', + 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('1.51390548675291000000')"), - 'tag__tag_id': '303', - 'threshold': GenericRepr("Decimal('0.62000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '802', + 'threshold': GenericRepr("Decimal('0.29999999999999998890')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '9', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00246191542828455570')"), - 'tag__tag_id': '304', - 'threshold': GenericRepr("Decimal('0.10000000000000000000')"), + 'prediction': GenericRepr("Decimal('-1.00000000000000000000')"), + 'tag__tag_id': '904', + 'threshold': GenericRepr("Decimal('-1.00000000000000000000')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '9', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.19748103480006374000')"), - 'tag__tag_id': '305', - 'threshold': GenericRepr("Decimal('0.43000000000000000000')"), + 'prediction': GenericRepr("Decimal('-1.00000000000000000000')"), + 'tag__tag_id': '905', + 'threshold': GenericRepr("Decimal('-1.00000000000000000000')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '9', 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', + 'draft_entry__excerpt': 'sample excerpt 101', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.13266879380965720000')"), - 'tag__tag_id': '306', - 'threshold': GenericRepr("Decimal('0.49000000000000000000')"), + 'prediction': GenericRepr("Decimal('-1.00000000000000000000')"), + 'tag__tag_id': '907', + 'threshold': GenericRepr("Decimal('-1.00000000000000000000')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '1', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00847395147300428900')"), - 'tag__tag_id': '307', - 'threshold': GenericRepr("Decimal('0.36000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00200000000000000004')"), + 'tag__tag_id': '101', + 'threshold': GenericRepr("Decimal('0.14000000000000001332')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '1', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, + 'is_selected': True, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.01439434579677051900')"), - 'tag__tag_id': '308', - 'threshold': GenericRepr("Decimal('0.45000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.64800000000000002043')"), + 'tag__tag_id': '102', + 'threshold': GenericRepr("Decimal('0.17000000000000001221')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '1', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00275349894147967100')"), - 'tag__tag_id': '309', - 'threshold': GenericRepr("Decimal('0.31000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.02699999999999999969')"), + 'tag__tag_id': '103', + 'threshold': GenericRepr("Decimal('0.10000000000000000555')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '1', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.02261752535293742000')"), - 'tag__tag_id': '310', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), + 'prediction': GenericRepr("Decimal('0.06199999999999999956')"), + 'tag__tag_id': '104', + 'threshold': GenericRepr("Decimal('0.14000000000000001332')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '2', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00280699276022220930')"), - 'tag__tag_id': '311', - 'threshold': GenericRepr("Decimal('0.38000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00700000000000000015')"), + 'tag__tag_id': '204', + 'threshold': GenericRepr("Decimal('0.14000000000000001332')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '2', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, + 'is_selected': True, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00353863737969235940')"), - 'tag__tag_id': '312', - 'threshold': GenericRepr("Decimal('0.33000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.45800000000000001821')"), + 'tag__tag_id': '209', + 'threshold': GenericRepr("Decimal('0.05000000000000000278')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '2', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00474455507679118000')"), - 'tag__tag_id': '313', - 'threshold': GenericRepr("Decimal('0.45000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '214', + 'threshold': GenericRepr("Decimal('0.08999999999999999667')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '2', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00243518249286959600')"), - 'tag__tag_id': '314', - 'threshold': GenericRepr("Decimal('0.24000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00300000000000000006')"), + 'tag__tag_id': '216', + 'threshold': GenericRepr("Decimal('0.13000000000000000444')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '2', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00498411668972535500')"), - 'tag__tag_id': '315', - 'threshold': GenericRepr("Decimal('0.55000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '217', + 'threshold': GenericRepr("Decimal('0.04000000000000000083')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '2', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00342778279446065430')"), - 'tag__tag_id': '316', - 'threshold': GenericRepr("Decimal('0.15000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00400000000000000008')"), + 'tag__tag_id': '218', + 'threshold': GenericRepr("Decimal('0.08999999999999999667')"), 'value': '' }, { - 'category__tag_id': '3', + 'category__tag_id': '2', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00183609818729261560')"), - 'tag__tag_id': '317', - 'threshold': GenericRepr("Decimal('0.30000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00300000000000000006')"), + 'tag__tag_id': '219', + 'threshold': GenericRepr("Decimal('0.13000000000000000444')"), 'value': '' }, { @@ -2262,86 +778,86 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00765169737860560400')"), - 'tag__tag_id': '318', - 'threshold': GenericRepr("Decimal('0.25000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '301', + 'threshold': GenericRepr("Decimal('0.01000000000000000021')"), 'value': '' }, { - 'category__tag_id': '4', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00020814205345232040')"), - 'tag__tag_id': '401', - 'threshold': GenericRepr("Decimal('0.25000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '302', + 'threshold': GenericRepr("Decimal('0.11000000000000000056')"), 'value': '' }, { - 'category__tag_id': '4', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00299776057263129780')"), - 'tag__tag_id': '402', - 'threshold': GenericRepr("Decimal('0.58000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.08300000000000000433')"), + 'tag__tag_id': '303', + 'threshold': GenericRepr("Decimal('0.38000000000000000444')"), 'value': '' }, { - 'category__tag_id': '4', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, + 'is_selected': True, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00299218206367056270')"), - 'tag__tag_id': '403', - 'threshold': GenericRepr("Decimal('0.14000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.08599999999999999312')"), + 'tag__tag_id': '304', + 'threshold': GenericRepr("Decimal('0.01000000000000000021')"), 'value': '' }, { - 'category__tag_id': '4', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00241597760274695900')"), - 'tag__tag_id': '404', - 'threshold': GenericRepr("Decimal('0.48000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00300000000000000006')"), + 'tag__tag_id': '315', + 'threshold': GenericRepr("Decimal('0.45000000000000001110')"), 'value': '' }, { - 'category__tag_id': '4', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.02053049989999868700')"), - 'tag__tag_id': '405', - 'threshold': GenericRepr("Decimal('0.78000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '316', + 'threshold': GenericRepr("Decimal('0.05999999999999999778')"), 'value': '' }, { - 'category__tag_id': '4', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00281014967745599850')"), - 'tag__tag_id': '406', - 'threshold': GenericRepr("Decimal('0.13000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00400000000000000008')"), + 'tag__tag_id': '317', + 'threshold': GenericRepr("Decimal('0.28000000000000002665')"), 'value': '' }, { - 'category__tag_id': '4', + 'category__tag_id': '3', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00022843408415366598')"), - 'tag__tag_id': '407', - 'threshold': GenericRepr("Decimal('0.41000000000000003000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '318', + 'threshold': GenericRepr("Decimal('0.13000000000000000444')"), 'value': '' }, { @@ -2350,9 +866,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00943289911848003600')"), - 'tag__tag_id': '408', - 'threshold': GenericRepr("Decimal('0.59000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '401', + 'threshold': GenericRepr("Decimal('0.28999999999999998002')"), 'value': '' }, { @@ -2361,20 +877,20 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00091892403101415500')"), - 'tag__tag_id': '409', - 'threshold': GenericRepr("Decimal('0.56000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '402', + 'threshold': GenericRepr("Decimal('0.45000000000000001110')"), 'value': '' }, { 'category__tag_id': '4', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, + 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('2.03979988487399360000')"), - 'tag__tag_id': '410', - 'threshold': GenericRepr("Decimal('0.49000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '407', + 'threshold': GenericRepr("Decimal('0.07000000000000000666')"), 'value': '' }, { @@ -2383,9 +899,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00750677951145917200')"), - 'tag__tag_id': '411', - 'threshold': GenericRepr("Decimal('0.20000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), + 'tag__tag_id': '408', + 'threshold': GenericRepr("Decimal('0.11000000000000000056')"), 'value': '' }, { @@ -2394,20 +910,20 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00019092757914525768')"), + 'prediction': GenericRepr("Decimal('0E-20')"), 'tag__tag_id': '412', - 'threshold': GenericRepr("Decimal('0.60000000000000000000')"), + 'threshold': GenericRepr("Decimal('0.35999999999999998668')"), 'value': '' }, { 'category__tag_id': '5', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, + 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('1.40336945023335200000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), 'tag__tag_id': '501', - 'threshold': GenericRepr("Decimal('0.71000000000000000000')"), + 'threshold': GenericRepr("Decimal('0.45000000000000001110')"), 'value': '' }, { @@ -2416,20 +932,20 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00778131599707359600')"), + 'prediction': GenericRepr("Decimal('0E-20')"), 'tag__tag_id': '502', - 'threshold': GenericRepr("Decimal('0.44000000000000000000')"), + 'threshold': GenericRepr("Decimal('0.47999999999999998224')"), 'value': '' }, { 'category__tag_id': '6', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, + 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.04068703080217044000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), 'tag__tag_id': '601', - 'threshold': GenericRepr("Decimal('0.48000000000000000000')"), + 'threshold': GenericRepr("Decimal('0.05999999999999999778')"), 'value': '' }, { @@ -2438,9 +954,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.02458783670921217300')"), + 'prediction': GenericRepr("Decimal('0.00100000000000000002')"), 'tag__tag_id': '602', - 'threshold': GenericRepr("Decimal('0.44000000000000000000')"), + 'threshold': GenericRepr("Decimal('0.47999999999999998224')"), 'value': '' }, { @@ -2449,9 +965,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.04259871318936348000')"), + 'prediction': GenericRepr("Decimal('0.02199999999999999872')"), 'tag__tag_id': '603', - 'threshold': GenericRepr("Decimal('0.40000000000000000000')"), + 'threshold': GenericRepr("Decimal('0.34000000000000002442')"), 'value': '' }, { @@ -2460,53 +976,20 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00641449491997234200')"), + 'prediction': GenericRepr("Decimal('0E-20')"), 'tag__tag_id': '604', - 'threshold': GenericRepr("Decimal('0.61000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00027582379877694870')"), - 'tag__tag_id': '801', - 'threshold': GenericRepr("Decimal('0.73000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00997524285181002000')"), - 'tag__tag_id': '802', - 'threshold': GenericRepr("Decimal('0.55000000000000000000')"), + 'threshold': GenericRepr("Decimal('0.16000000000000000333')"), 'value': '' }, { - 'category__tag_id': '8', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00476177378710526100')"), - 'tag__tag_id': '803', - 'threshold': GenericRepr("Decimal('0.67000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '8', + 'category__tag_id': '7', 'data_type': 1, 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00084620605533321700')"), - 'tag__tag_id': '804', - 'threshold': GenericRepr("Decimal('0.75000000000000000000')"), + 'prediction': GenericRepr("Decimal('0.00800000000000000017')"), + 'tag__tag_id': '701', + 'threshold': GenericRepr("Decimal('0.27000000000000001776')"), 'value': '' }, { @@ -2515,9 +998,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00070480359681823760')"), - 'tag__tag_id': '805', - 'threshold': GenericRepr("Decimal('0.64000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '801', + 'threshold': GenericRepr("Decimal('0.66000000000000003109')"), 'value': '' }, { @@ -2526,20 +1009,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.00703320267416958500')"), - 'tag__tag_id': '806', - 'threshold': GenericRepr("Decimal('0.53000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '902', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), + 'prediction': GenericRepr("Decimal('0E-20')"), + 'tag__tag_id': '802', + 'threshold': GenericRepr("Decimal('0.29999999999999998890')"), 'value': '' }, { @@ -2548,20 +1020,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '903', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), + 'prediction': GenericRepr("Decimal('-1.00000000000000000000')"), 'tag__tag_id': '904', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), + 'threshold': GenericRepr("Decimal('-1.00000000000000000000')"), 'value': '' }, { @@ -2570,20 +1031,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), + 'prediction': GenericRepr("Decimal('-1.00000000000000000000')"), 'tag__tag_id': '905', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '9', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': False, - 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), - 'tag__tag_id': '906', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), + 'threshold': GenericRepr("Decimal('-1.00000000000000000000')"), 'value': '' }, { @@ -2592,31 +1042,9 @@ 'draft_entry__excerpt': 'sample excerpt 102', 'is_selected': False, 'model_version__model__model_id': 'all_tags_model', - 'prediction': GenericRepr("Decimal('0.50000000000000000000')"), + 'prediction': GenericRepr("Decimal('-1.00000000000000000000')"), 'tag__tag_id': '907', - 'threshold': GenericRepr("Decimal('0.50000000000000000000')"), - 'value': '' - }, - { - 'category__tag_id': '10', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 101', - 'is_selected': True, - 'model_version__model__model_id': 'reliability', - 'prediction': None, - 'tag__tag_id': '1002', - 'threshold': None, - 'value': '' - }, - { - 'category__tag_id': '10', - 'data_type': 1, - 'draft_entry__excerpt': 'sample excerpt 102', - 'is_selected': True, - 'model_version__model__model_id': 'reliability', - 'prediction': None, - 'tag__tag_id': '1002', - 'threshold': None, + 'threshold': GenericRepr("Decimal('-1.00000000000000000000')"), 'value': '' } ] @@ -2713,69 +1141,6 @@ 'parent_tag__tag_id': '1', 'tag_id': '104' }, - { - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'is_deprecated': False, - 'name': 'Health', - 'parent_tag__tag_id': '1', - 'tag_id': '105' - }, - { - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'is_deprecated': False, - 'name': 'Livelihoods', - 'parent_tag__tag_id': '1', - 'tag_id': '106' - }, - { - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'is_deprecated': False, - 'name': 'Logistics', - 'parent_tag__tag_id': '1', - 'tag_id': '107' - }, - { - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'is_deprecated': False, - 'name': 'Nutrition', - 'parent_tag__tag_id': '1', - 'tag_id': '108' - }, - { - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'is_deprecated': False, - 'name': 'Protection', - 'parent_tag__tag_id': '1', - 'tag_id': '109' - }, - { - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'is_deprecated': False, - 'name': 'Shelter', - 'parent_tag__tag_id': '1', - 'tag_id': '110' - }, - { - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'is_deprecated': False, - 'name': 'WASH', - 'parent_tag__tag_id': '1', - 'tag_id': '111' - }, { 'group': None, 'hide_in_analysis_framework_mapping': True, diff --git a/apps/assisted_tagging/tests/test_query.py b/apps/assisted_tagging/tests/test_query.py index 63488b594a..119b999bfb 100644 --- a/apps/assisted_tagging/tests/test_query.py +++ b/apps/assisted_tagging/tests/test_query.py @@ -331,518 +331,230 @@ def _query_check(**kwargs): class AssistedTaggingCallbackApiTest(TestCase, SnapShotTextCase): + factories_used = [ + UserFactory, + ProjectFactory, + LeadFactory, + AssistedTaggingModelFactory, + AssistedTaggingModelPredictionTagFactory, + AssistedTaggingModelVersionFactory, + DraftEntryFactory, + AssistedTaggingPredictionFactory, + MissingPredictionReviewFactory, + WrongPredictionReviewFactory, + ] DEEPL_CALLBACK_MOCK_DATA = { - 'client_id': 'random-client-id', - 'model_preds': [ - { - 'tags': { - '1': { - '101': { - 'prediction': 0.0013131533306455466, - 'threshold': 0.41000000000000003, - 'is_selected': False, - }, - '103': { - 'prediction': 0.003010824160731357, - 'threshold': 0.46, - 'is_selected': False, - }, - '104': { - 'prediction': 0.002566287973119567, - 'threshold': 0.48, - 'is_selected': False, - }, - '105': { - 'prediction': 2.677955230077108, - 'threshold': 0.36, - 'is_selected': True, - }, - '106': { - 'prediction': 0.01722483797685096, - 'threshold': 0.38, - 'is_selected': False, - }, - '107': { - 'prediction': 0.003670748323202133, - 'threshold': 0.5, - 'is_selected': False, - }, - '108': { - 'prediction': 0.0041013412481668045, - 'threshold': 0.49, - 'is_selected': False, - }, - '109': { - 'prediction': 0.028100471686700296, - 'threshold': 0.58, - 'is_selected': False, - }, - '110': { - 'prediction': 0.0035644680749447573, - 'threshold': 0.42, - 'is_selected': False, - }, - '111': { - 'prediction': 0.00885658950175879, - 'threshold': 0.53, - 'is_selected': False, - } - }, - '3': { - '301': { - 'prediction': 0.00023104241032948875, - 'threshold': 0.12, - 'is_selected': False, - }, - '302': { - 'prediction': 0.006840221311261014, - 'threshold': 0.41000000000000003, - 'is_selected': False, - }, - '303': { - 'prediction': 1.51390548675291, - 'threshold': 0.62, - 'is_selected': True, - }, - '304': { - 'prediction': 0.0024619154282845557, - 'threshold': 0.1, - 'is_selected': False, - }, - '305': { - 'prediction': 0.19748103480006374, - 'threshold': 0.43, - 'is_selected': False, - }, - '306': { - 'prediction': 0.1326687938096572, - 'threshold': 0.49, - 'is_selected': False, - }, - '307': { - 'prediction': 0.008473951473004289, - 'threshold': 0.36, - 'is_selected': False, - }, - '308': { - 'prediction': 0.014394345796770519, - 'threshold': 0.45, - 'is_selected': False, - }, - '309': { - 'prediction': 0.002753498941479671, - 'threshold': 0.31, - 'is_selected': False, - }, - '310': { - 'prediction': 0.02261752535293742, - 'threshold': 0.41000000000000003, - 'is_selected': False, - }, - '311': { - 'prediction': 0.0028069927602222093, - 'threshold': 0.38, - 'is_selected': False, - }, - '312': { - 'prediction': 0.0035386373796923594, - 'threshold': 0.33, - 'is_selected': False, - }, - '313': { - 'prediction': 0.00474455507679118, - 'threshold': 0.45, - 'is_selected': False, - }, - '314': { - 'prediction': 0.002435182492869596, - 'threshold': 0.24, - 'is_selected': False, - }, - '315': { - 'prediction': 0.004984116689725355, - 'threshold': 0.55, - 'is_selected': False, - }, - '316': { - 'prediction': 0.0034277827944606543, - 'threshold': 0.15, - 'is_selected': False, - }, - '317': { - 'prediction': 0.0018360981872926156, - 'threshold': 0.3, - 'is_selected': False, - }, - '318': { - 'prediction': 0.007651697378605604, - 'threshold': 0.25, - 'is_selected': False, - } - }, - '2': { - '219': { - 'prediction': 0.0018779816205746359, - 'threshold': 0.28, - 'is_selected': False, - }, - '217': { - 'prediction': 0.0009131004424908987, - 'threshold': 0.13, - 'is_selected': False, - }, - '218': { - 'prediction': 0.0010629182305330266, - 'threshold': 0.13, - 'is_selected': False, - }, - '204': { - 'prediction': 0.01951472795739466, - 'threshold': 0.49, - 'is_selected': False, - }, - '203': { - 'prediction': 0.002760568168014288, - 'threshold': 0.41000000000000003, - 'is_selected': False, - }, - '201': { - 'prediction': 0.001610475469772753, - 'threshold': 0.38, - 'is_selected': False, - }, - '205': { - 'prediction': 0.0028414463984870143, - 'threshold': 0.31, - 'is_selected': False, - }, - '207': { - 'prediction': 0.0030019306965793175, - 'threshold': 0.3, - 'is_selected': False, - }, - '206': { - 'prediction': 0.0028423364380035887, - 'threshold': 0.44, - 'is_selected': False, - }, - '202': { - 'prediction': 0.0024926103993921592, - 'threshold': 0.17, - 'is_selected': False, - }, - '228': { - 'prediction': 0.004972799797542393, - 'threshold': 0.8, - 'is_selected': False, - }, - '229': { - 'prediction': 0.00032880847216941987, - 'threshold': 0.39, - 'is_selected': False, - }, - '230': { - 'prediction': 0.001167356436152333, - 'threshold': 0.81, - 'is_selected': False, - }, - '231': { - 'prediction': 0.0024493522487762497, - 'threshold': 0.41000000000000003, - 'is_selected': False, - }, - '232': { - 'prediction': 0.005428578056718992, - 'threshold': 0.46, - 'is_selected': False, - }, - '233': { - 'prediction': 0.0018874364551392537, - 'threshold': 0.79, - 'is_selected': False, - }, - '234': { - 'prediction': 0.0011778841898949057, - 'threshold': 0.54, - 'is_selected': False, - }, - '215': { - 'prediction': 0.0004781786533146116, - 'threshold': 0.38, - 'is_selected': False, - }, - '216': { - 'prediction': 0.006963967811316252, - 'threshold': 0.25, - 'is_selected': False, - }, - '214': { - 'prediction': 0.0003674881209635401, - 'threshold': 0.29, - 'is_selected': False, - }, - '213': { - 'prediction': 0.0002446720680234501, - 'threshold': 0.37, - 'is_selected': False, - }, - '212': { - 'prediction': 0.012378716890357043, - 'threshold': 0.38, - 'is_selected': False, - }, - '223': { - 'prediction': 0.001155513591390658, - 'threshold': 0.47000000000000003, - 'is_selected': False, - }, - '222': { - 'prediction': 0.0014652756362920627, - 'threshold': 0.48, - 'is_selected': False, - }, - '221': { - 'prediction': 0.001666667767016119, - 'threshold': 0.19, - 'is_selected': False, - }, - '220': { - 'prediction': 0.011259256380385366, - 'threshold': 0.29, - 'is_selected': False, - }, - '224': { - 'prediction': 0.007581055563475405, - 'threshold': 0.21, - 'is_selected': False, - }, - '225': { - 'prediction': 0.0003372832482758289, - 'threshold': 0.15, - 'is_selected': False, - }, - '227': { - 'prediction': 0.0009009759297542688, - 'threshold': 0.18, - 'is_selected': False, - }, - '226': { - 'prediction': 0.0007702910806983709, - 'threshold': 0.18, - 'is_selected': False, - }, - '210': { - 'prediction': 0.006979638609387304, - 'threshold': 0.23, - 'is_selected': False, - }, - '208': { - 'prediction': 0.00357941840775311, - 'threshold': 0.2, - 'is_selected': False, - }, - '209': { - 'prediction': 0.006321697112391976, - 'threshold': 0.17, - 'is_selected': False, - } - }, - '6': { - '601': { - 'prediction': 0.04068703080217044, - 'threshold': 0.48, - 'is_selected': True, - }, - '602': { - 'prediction': 0.024587836709212173, - 'threshold': 0.44, - 'is_selected': False, - }, - '603': { - 'prediction': 0.04259871318936348, - 'threshold': 0.4, - 'is_selected': False, - }, - '604': { - 'prediction': 0.006414494919972342, - 'threshold': 0.61, - 'is_selected': False, - } - }, - '5': { - '501': { - 'prediction': 1.403369450233352, - 'threshold': 0.71, - 'is_selected': True, - }, - '502': { - 'prediction': 0.007781315997073596, - 'threshold': 0.44, - 'is_selected': False, - } - }, - '8': { - '801': { - 'prediction': 0.0002758237987769487, - 'threshold': 0.73, - 'is_selected': False, - }, - '802': { - 'prediction': 0.00997524285181002, - 'threshold': 0.55, - 'is_selected': False, - }, - '803': { - 'prediction': 0.004761773787105261, - 'threshold': 0.67, - 'is_selected': False, - }, - '804': { - 'prediction': 0.000846206055333217, - 'threshold': 0.75, - 'is_selected': False, - }, - '805': { - 'prediction': 0.0007048035968182376, - 'threshold': 0.64, - 'is_selected': False, - }, - '806': { - 'prediction': 0.007033202674169585, - 'threshold': 0.53, - 'is_selected': False, - } - }, - '4': { - '401': { - 'prediction': 0.0002081420534523204, - 'threshold': 0.25, - 'is_selected': False, - }, - '402': { - 'prediction': 0.0029977605726312978, - 'threshold': 0.58, - 'is_selected': False, - }, - '403': { - 'prediction': 0.0029921820636705627, - 'threshold': 0.14, - 'is_selected': False, - }, - '404': { - 'prediction': 0.002415977602746959, - 'threshold': 0.48, - 'is_selected': False, - }, - '405': { - 'prediction': 0.020530499899998687, - 'threshold': 0.78, - 'is_selected': False, - }, - '406': { - 'prediction': 0.0028101496774559985, - 'threshold': 0.13, - 'is_selected': False, - }, - '407': { - 'prediction': 0.00022843408415366598, - 'threshold': 0.41000000000000003, - 'is_selected': False, - }, - '408': { - 'prediction': 0.009432899118480036, - 'threshold': 0.59, - 'is_selected': False, - }, - '409': { - 'prediction': 0.000918924031014155, - 'threshold': 0.56, - 'is_selected': False, - }, - '410': { - 'prediction': 2.0397998848739936, - 'threshold': 0.49, - 'is_selected': True, - }, - '411': { - 'prediction': 0.007506779511459172, - 'threshold': 0.2, - 'is_selected': False, - }, - '412': { - 'prediction': 0.00019092757914525768, - 'threshold': 0.6, - 'is_selected': False, - } - }, - '9': { - '904': { - 'prediction': 0.5, - 'threshold': 0.5, - 'is_selected': True, - }, - '905': { - 'prediction': 0.5, - 'threshold': 0.5, - 'is_selected': False, - }, - '902': { - 'prediction': 0.5, - 'threshold': 0.5, - 'is_selected': False, - }, - '903': { - 'prediction': 0.5, - 'threshold': 0.5, - 'is_selected': False, - }, - '906': { - 'prediction': 0.5, - 'threshold': 0.5, - 'is_selected': False, - }, - '907': { - 'prediction': 0.5, - 'threshold': 0.5, - 'is_selected': False, - } - } + "client_id": "random-client-id", + "model_tags": { + "1": { + "101": { + "prediction": 0.002, + "threshold": 0.14, + "is_selected": False }, - 'prediction_status': 1, - 'model_info': { - 'id': 'all_tags_model', - 'version': '1.0.0', + "102": { + "prediction": 0.648, + "threshold": 0.17, + "is_selected": True + }, + "103": { + "prediction": 0.027, + "threshold": 0.1, + "is_selected": False + }, + "104": { + "prediction": 0.062, + "threshold": 0.14, + "is_selected": False } }, - { - 'model_info': { - 'id': 'geolocation', - 'version': '1.0.0', + "3": { + "301": { + "prediction": 0.001, + "threshold": 0.01, + "is_selected": False }, - 'values': [ - 'Nepal', - 'Paris', - ], - 'prediction_status': 1 + "302": { + "prediction": 0.001, + "threshold": 0.11, + "is_selected": False + }, + "303": { + "prediction": 0.083, + "threshold": 0.38, + "is_selected": False + }, + "304": { + "prediction": 0.086, + "threshold": 0.01, + "is_selected": True + }, + "315": { + "prediction": 0.003, + "threshold": 0.45, + "is_selected": False + }, + "316": { + "prediction": 0.001, + "threshold": 0.06, + "is_selected": False + }, + "317": { + "prediction": 0.004, + "threshold": 0.28, + "is_selected": False + }, + "318": { + "prediction": 0.0, + "threshold": 0.13, + "is_selected": False + } + }, + "2": { + "219": { + "prediction": 0.003, + "threshold": 0.13, + "is_selected": False + }, + "217": { + "prediction": 0.001, + "threshold": 0.04, + "is_selected": False + }, + "218": { + "prediction": 0.004, + "threshold": 0.09, + "is_selected": False + }, + "204": { + "prediction": 0.007, + "threshold": 0.14, + "is_selected": False + }, + "216": { + "prediction": 0.003, + "threshold": 0.13, + "is_selected": False + }, + "214": { + "prediction": 0.001, + "threshold": 0.09, + "is_selected": False + }, + "209": { + "prediction": 0.458, + "threshold": 0.05, + "is_selected": True + } + }, + "6": { + "601": { + "prediction": 0.0, + "threshold": 0.06, + "is_selected": False + }, + "602": { + "prediction": 0.001, + "threshold": 0.48, + "is_selected": False + }, + "603": { + "prediction": 0.022, + "threshold": 0.34, + "is_selected": False + }, + "604": { + "prediction": 0.0, + "threshold": 0.16, + "is_selected": False + } + }, + "5": { + "501": { + "prediction": 0.0, + "threshold": 0.45, + "is_selected": False + }, + "502": { + "prediction": 0.0, + "threshold": 0.48, + "is_selected": False + } + }, + "8": { + "801": { + "prediction": 0.0, + "threshold": 0.66, + "is_selected": False + }, + "802": { + "prediction": 0.0, + "threshold": 0.3, + "is_selected": False + } }, - { - 'model_info': { - 'id': 'reliability', - 'version': '1.0.0', + "4": { + "401": { + "prediction": 0.001, + "threshold": 0.29, + "is_selected": False }, - 'tags': { - '10': { - '1002': { - 'is_selected': True, - } - } + "402": { + "prediction": 0.001, + "threshold": 0.45, + "is_selected": False }, - 'prediction_status': 1 + "407": { + "prediction": 0.0, + "threshold": 0.07, + "is_selected": False + }, + "408": { + "prediction": 0.001, + "threshold": 0.11, + "is_selected": False + }, + "412": { + "prediction": 0.0, + "threshold": 0.36, + "is_selected": False + } + }, + "7": { + "701": { + "prediction": 0.008, + "threshold": 0.27, + "is_selected": False + } + }, + "9": { + "904": { + "prediction": -1, + "threshold": -1, + "is_selected": False + }, + "905": { + "prediction": -1, + "threshold": -1, + "is_selected": False + }, + "907": { + "prediction": -1, + "threshold": -1, + "is_selected": False + } } - ] + }, + "geolocations": [ + "New York" + ], + "model_info": { + "id": "all_tags_model", + "version": "1.0.0" + }, + "prediction_status": True } - DEEPL_TAGS_MOCK_RESPONSE = { '101': { 'label': 'Agriculture', @@ -872,55 +584,6 @@ class AssistedTaggingCallbackApiTest(TestCase, SnapShotTextCase): 'is_category': False, 'parent_id': '1', }, - '105': { - 'label': 'Health', - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'parent_id': '1', - }, - '106': { - 'label': 'Livelihoods', - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'parent_id': '1', - }, - '107': { - 'label': 'Logistics', - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'parent_id': '1', - }, - '108': { - 'label': 'Nutrition', - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'parent_id': '1', - }, - '109': { - 'label': 'Protection', - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'parent_id': '1', - }, - '110': { - 'label': 'Shelter', - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'parent_id': '1', - }, - '111': { - 'label': 'WASH', - 'group': 'Sectors', - 'hide_in_analysis_framework_mapping': False, - 'is_category': False, - 'parent_id': '1', - }, '201': { 'label': 'Environment', 'group': 'Context', @@ -1621,13 +1284,13 @@ def _get_current_model_stats(): model_version_count=AssistedTaggingModelVersion.objects.count(), tag_count=AssistedTaggingModelPredictionTag.objects.count(), models=list( - AssistedTaggingModel.objects.values('model_id', 'name') + AssistedTaggingModel.objects.values('model_id', 'name').order_by('model_id') ), model_versions=list( - AssistedTaggingModelVersion.objects.values('model__model_id', 'version') + AssistedTaggingModelVersion.objects.values('model__model_id', 'version').order_by('model__model_id') ), tags=list( - AssistedTaggingModelPredictionTag.objects.values('name', 'tag_id', 'is_deprecated') + AssistedTaggingModelPredictionTag.objects.values('name', 'tag_id', 'is_deprecated').order_by('tag_id') ), ) diff --git a/apps/deepl_integration/handlers.py b/apps/deepl_integration/handlers.py index e5991df3e1..846a4626b2 100644 --- a/apps/deepl_integration/handlers.py +++ b/apps/deepl_integration/handlers.py @@ -188,7 +188,7 @@ def send_trigger_request_to_extractor(cls, draft_entry): headers=cls.REQUEST_HEADERS, json=payload ) - if response.status_code == 200: + if response.status_code == 202: return True except Exception: logger.error('Assisted tagging send failed, Exception occurred!!', exc_info=True) @@ -259,7 +259,8 @@ def get_tags_map(): current_tags_map = get_tags_map() # Check if new tags needs to be created new_tags = [ - tag for tag in tags + tag + for tag in tags if tag not in current_tags_map ] if new_tags: @@ -279,10 +280,10 @@ def get_tags_map(): @classmethod def _process_model_preds(cls, model_version, current_tags_map, draft_entry, model_prediction): prediction_status = model_prediction['prediction_status'] - if prediction_status == 0: # If 0 no tags are provided + if not prediction_status: # If False no tags are provided return - tags = model_prediction.get('tags', {}) # NLP TagId + tags = model_prediction.get('model_tags', {}) # NLP TagId values = model_prediction.get('values', []) # Raw value common_attrs = dict( @@ -320,34 +321,230 @@ def _process_model_preds(cls, model_version, current_tags_map, draft_entry, mode @classmethod def save_data(cls, draft_entry, data): - model_preds = data['model_preds'] + model_preds = data # Save if new tags are provided current_tags_map = cls._get_or_create_tags_map([ tag - for prediction in model_preds - for category_tag, tags in prediction.get('tags', {}).items() + for category_tag, tags in model_preds['model_tags'].items() for tag in [ category_tag, *tags.keys(), ] ]) - models_version_map = cls._get_or_create_models_version([ - prediction['model_info'] - for prediction in model_preds - ]) - + models_version_map = cls._get_or_create_models_version( + [ + model_preds['model_info'] + ] + ) with transaction.atomic(): draft_entry.clear_data() # Clear old data if exists draft_entry.calculated_at = timezone.now() - for prediction in model_preds: - model_version = models_version_map[(prediction['model_info']['id'], prediction['model_info']['version'])] - cls._process_model_preds(model_version, current_tags_map, draft_entry, prediction) + model_version = models_version_map[(model_preds['model_info']['id'], model_preds['model_info']['version'])] + cls._process_model_preds(model_version, current_tags_map, draft_entry, model_preds) draft_entry.prediction_status = DraftEntry.PredictionStatus.DONE draft_entry.save_geo_data() draft_entry.save() return draft_entry +class AutoAssistedTaggingDraftEntryHandler(BaseHandler): + # TODO: Fix N+1 issues here. Try to do bulk_update for each models. + # Or do this Async + model = Lead + callback_url_name = 'auto-assisted_tagging_draft_entry_prediction_callback' + + @classmethod + def auto_trigger_request_to_extractor(cls, lead): + lead_preview = LeadPreview.objects.get(lead=lead) + payload = { + "documents": [ + { + "client_id": cls.get_client_id(lead), # static clientid for mock + "text_extraction_id": str(lead_preview.text_extraction_id) + } + ], + "callback_url": cls.get_callback_url() + } + try: + response = requests.post( + url=DeeplServiceEndpoint.ENTRY_EXTRACTION_CLASSIFICATION, + headers=cls.REQUEST_HEADERS, + json=payload + ) + if response.status_code == 202: + lead.auto_entry_extraction_status = Lead.AutoExtractionStatus.PENDING + lead.save(update_fields=('auto_entry_extraction_status',)) + return True + + except Exception: + logger.error('Entry Extraction send failed, Exception occurred!!', exc_info=True) + _response = locals().get('response') + logger.error( + 'Entry Extraction send failed!!', + extra={ + 'payload': payload, + 'response': _response.content if _response else None + }, + ) + + @staticmethod + def _get_or_create_models_version(models_data): + def get_versions_map(): + return { + (model_version.model.model_id, model_version.version): model_version + for model_version in AssistedTaggingModelVersion.objects.filter( + reduce( + lambda acc, item: acc | item, + [ + models.Q( + model__model_id=model_data['name'], + version=model_data['version'], + ) + for model_data in models_data + ], + ) + ).select_related('model').all() + } + + existing_model_versions = get_versions_map() + new_model_versions = [ + model_data + for model_data in models_data + if (model_data['name'], model_data['version']) not in existing_model_versions + ] + + if new_model_versions: + AssistedTaggingModelVersion.objects.bulk_create([ + AssistedTaggingModelVersion( + model=AssistedTaggingModel.objects.get_or_create( + model_id=model_data['name'], + defaults=dict( + name=model_data['name'], + ), + )[0], + version=model_data['version'], + ) + for model_data in models_data + ]) + existing_model_versions = get_versions_map() + return existing_model_versions + + @classmethod + def _get_or_create_tags_map(cls, tags): + from assisted_tagging.tasks import sync_tags_with_deepl_task + + def get_tags_map(): + return { + tag_id: _id + for _id, tag_id in AssistedTaggingModelPredictionTag.objects.values_list('id', 'tag_id') + } + + current_tags_map = get_tags_map() + # Check if new tags needs to be created + new_tags = [ + tag for tag in tags + if tag not in current_tags_map + ] + if new_tags: + # Create new tags + AssistedTaggingModelPredictionTag.objects.bulk_create([ + AssistedTaggingModelPredictionTag( + name=new_tag, + tag_id=new_tag, + ) + for new_tag in new_tags + ]) + # Refetch + current_tags_map = get_tags_map() + sync_tags_with_deepl_task.delay() + return current_tags_map + + @classmethod + def _process_model_preds(cls, model_version, current_tags_map, draft_entry, model_prediction): + prediction_status = model_prediction['prediction_status'] + if not prediction_status: # If False no tags are provided + return + + tags = model_prediction.get('classification', {}) # NLP TagId + values = model_prediction.get('values', []) # Raw value + common_attrs = dict( + model_version=model_version, + draft_entry_id=draft_entry.id, + ) + new_predictions = [] + for category_tag, tags in tags.items(): + common_attrs = dict( + model_version=model_version, + draft_entry_id=draft_entry.id + ) + for tag, prediction_data in tags.items(): + prediction_value = prediction_data.get('prediction') + threshold_value = prediction_data.get('threshold') + is_selected = prediction_data.get('is_selected', False) + new_predictions.append( + AssistedTaggingPrediction( + **common_attrs, + data_type=AssistedTaggingPrediction.DataType.TAG, + category_id=current_tags_map[category_tag], + tag_id=current_tags_map[tag], + prediction=prediction_value, + threshold=threshold_value, + is_selected=is_selected, + ) + ) + + for value in set(values): + new_predictions.append( + AssistedTaggingPrediction( + **common_attrs, + data_type=AssistedTaggingPrediction.DataType.RAW, + value=value, + is_selected=True, + ) + ) + AssistedTaggingPrediction.objects.bulk_create(new_predictions) + + @classmethod + @transaction.atomic + def save_data(cls, lead, data_url): + # NOTE: Schema defined here + # - https://docs.google.com/document/d/1NmjOO5sOrhJU6b4QXJBrGAVk57_NW87mLJ9wzeY_NZI/edit#heading=h.t3u7vdbps5pt + data = RequestHelper(url=data_url, ignore_error=True).json() + draft_entry_qs = DraftEntry.objects.filter(lead=lead, type=DraftEntry.Type.AUTO) + if draft_entry_qs.exists(): + raise serializers.ValidationError('Draft entries already exit') + for model_preds in data['blocks']: + if not model_preds['relevant']: + continue + classification = model_preds['classification'] + current_tags_map = cls._get_or_create_tags_map([ + tag + for category_tag, tags in classification.items() + for tag in [ + category_tag, + *tags.keys(), + ] + ]) + models_version_map = cls._get_or_create_models_version([ + data['classification_model_info'] + ]) + + draft = DraftEntry.objects.create( + project=lead.project, + lead=lead, + excerpt=model_preds['text'], + prediction_status=DraftEntry.PredictionStatus.DONE, + type=DraftEntry.Type.AUTO + ) + model_version = models_version_map[ + (data['classification_model_info']['name'], data['classification_model_info']['version']) + ] + cls._process_model_preds(model_version, current_tags_map, draft, model_preds) + lead.auto_entry_extraction_status = Lead.AutoExtractionStatus.SUCCESS + lead.save(update_fields=('auto_entry_extraction_status',)) + return lead + + class LeadExtractionHandler(BaseHandler): model = Lead callback_url_name = 'lead_extract_callback' @@ -372,7 +569,7 @@ def send_trigger_request_to_extractor( headers=cls.REQUEST_HEADERS, data=json.dumps(payload) ) - if response.status_code == 200: + if response.status_code == 202: return True except Exception: logger.error('Lead Extraction Failed, Exception occurred!!', exc_info=True) @@ -425,6 +622,7 @@ def save_data( images_uri: List[str], word_count: int, page_count: int, + text_extraction_id: str ): LeadPreview.objects.filter(lead=lead).delete() LeadPreviewImage.objects.filter(lead=lead).delete() @@ -435,6 +633,7 @@ def save_data( text_extract=RequestHelper(url=text_source_uri, ignore_error=True).get_text(sanitize=True) or '', word_count=word_count, page_count=page_count, + text_extraction_id=text_extraction_id ) # Save extracted images as LeadPreviewImage instances # TODO: The logic is same for unified_connector leads as well. Maybe have a single func? @@ -814,4 +1013,4 @@ def save_data( geo_task.status = AnalyticalStatementGeoTask.Status.SUCCESS else: geo_task.status = AnalyticalStatementGeoTask.Status.FAILED - geo_task.save() + geo_task.save(update_fields=('status',)) diff --git a/apps/deepl_integration/serializers.py b/apps/deepl_integration/serializers.py index 6b263d2004..0f0924dcf5 100644 --- a/apps/deepl_integration/serializers.py +++ b/apps/deepl_integration/serializers.py @@ -12,6 +12,7 @@ AnalysisAutomaticSummaryHandler, AnalyticalStatementNGramHandler, AnalyticalStatementGeoHandler, + AutoAssistedTaggingDraftEntryHandler ) from deduplication.tasks.indexing import index_lead_and_calculate_duplicates @@ -63,16 +64,16 @@ class LeadExtractCallbackSerializer(DeeplServerBaseCallbackSerializer): """ Serialize deepl extractor """ - url = serializers.CharField() + url = serializers.CharField(required=False) # Data fields images_path = serializers.ListField( child=serializers.CharField(allow_blank=True), required=False, default=[], ) - text_path = serializers.CharField(required=False) - total_words_count = serializers.IntegerField(required=False, default=0) - total_pages = serializers.IntegerField(required=False, default=0) - + text_path = serializers.CharField(required=False, allow_null=True) + total_words_count = serializers.IntegerField(required=False, default=0, allow_null=True) + total_pages = serializers.IntegerField(required=False, default=0, allow_null=True) + text_extraction_id = serializers.CharField(required=True) nlp_handler = LeadExtractionHandler def validate(self, data): @@ -101,6 +102,7 @@ def create(self, data): data.get('images_path', [])[:10], # TODO: Support for more images, too much image will error. data.get('total_words_count'), data.get('total_pages'), + data.get('text_extraction_id') ) # Add to deduplication index transaction.on_commit(lambda: index_lead_and_calculate_duplicates.delay(lead.id)) @@ -158,9 +160,6 @@ def create(self, data): # --- AssistedTagging class AssistedTaggingModelPredictionCallbackSerializer(serializers.Serializer): - class ModelInfoCallbackSerializer(serializers.Serializer): - id = serializers.CharField() - version = serializers.CharField() class ModelPredictionCallbackSerializerTagValue(serializers.Serializer): prediction = serializers.DecimalField( @@ -177,7 +176,7 @@ class ModelPredictionCallbackSerializerTagValue(serializers.Serializer): ) is_selected = serializers.BooleanField() - model_info = ModelInfoCallbackSerializer() + # model_info = ModelInfoCallbackSerializer() removed from the DEEPL TODO Use different api for model information values = serializers.ListSerializer( child=serializers.CharField(), required=False, @@ -188,12 +187,38 @@ class ModelPredictionCallbackSerializerTagValue(serializers.Serializer): ), required=False, ) - prediction_status = serializers.IntegerField() # 0 -> Failure, 1 -> Success -class AssistedTaggingDraftEntryPredictionCallbackSerializer(BaseCallbackSerializer): - model_preds = AssistedTaggingModelPredictionCallbackSerializer(many=True) +class AutoAssistedTaggingModelPredicationCallBackSerializer(serializers.Serializer): + class ModelPredictionCallbackSerializerTagValue(serializers.Serializer): + predication = serializers.DecimalField( + max_digits=AssistedTaggingPrediction.prediction.field.max_digits, + decimal_places=AssistedTaggingPrediction.prediction.field.decimal_places, + required=False, + ) + threshold = serializers.DecimalField( + # From apps/assisted_tagging/models.py::AssistedTaggingPrediction::threshold + max_digits=AssistedTaggingPrediction.threshold.field.max_digits, + decimal_places=AssistedTaggingPrediction.threshold.field.decimal_places, + required=False, + ) + is_selected = serializers.BooleanField() + values = serializers.ListSerializer( + child=serializers.CharField(), + required=False, + ) + tags = serializers.DictField( + child=serializers.DictField( + child=ModelPredictionCallbackSerializerTagValue(), + ), + required=False, + ) + +class AssistedTaggingDraftEntryPredictionCallbackSerializer(BaseCallbackSerializer): + model_tags = serializers.DictField(child=serializers.DictField()) + prediction_status = serializers.BooleanField() + model_info = serializers.DictField() nlp_handler = AssistedTaggingDraftEntryHandler def create(self, validated_data): @@ -206,6 +231,27 @@ def create(self, validated_data): ) +class AutoAssistedBlockPredicationCallbackSerializer(serializers.Serializer): + text = serializers.CharField() + relevant = serializers.BooleanField() + prediction_status = serializers.BooleanField() + classification = serializers.DictField(child=serializers.DictField()) + + +class AutoAssistedTaggingDraftEntryCallbackSerializer(BaseCallbackSerializer): + entry_extraction_classification_path = serializers.URLField(required=True) + text_extraction_id = serializers.CharField(required=True) + status = serializers.IntegerField() + nlp_handler = AutoAssistedTaggingDraftEntryHandler + + def create(self, validated_data): + obj = validated_data['object'] + return self.nlp_handler.save_data( + obj, + validated_data['entry_extraction_classification_path'], + ) + + class EntriesCollectionBaseCallbackSerializer(DeeplServerBaseCallbackSerializer): model: Type[DeeplTrackBaseModel] presigned_s3_url = serializers.URLField() diff --git a/apps/deepl_integration/views.py b/apps/deepl_integration/views.py index d6163d0931..264d0ce6ec 100644 --- a/apps/deepl_integration/views.py +++ b/apps/deepl_integration/views.py @@ -15,6 +15,7 @@ AnalysisAutomaticSummaryCallbackSerializer, AnalyticalStatementNGramCallbackSerializer, AnalyticalStatementGeoCallbackSerializer, + AutoAssistedTaggingDraftEntryCallbackSerializer ) @@ -33,6 +34,10 @@ class AssistedTaggingDraftEntryPredictionCallbackView(BaseCallbackView): serializer = AssistedTaggingDraftEntryPredictionCallbackSerializer +class AutoTaggingDraftEntryPredictionCallbackView(BaseCallbackView): + serializer = AutoAssistedTaggingDraftEntryCallbackSerializer + + class LeadExtractCallbackView(BaseCallbackView): serializer = LeadExtractCallbackSerializer diff --git a/apps/lead/dataloaders.py b/apps/lead/dataloaders.py index 408d70ca49..bef4bdcf9d 100644 --- a/apps/lead/dataloaders.py +++ b/apps/lead/dataloaders.py @@ -13,6 +13,7 @@ from organization.dataloaders import OrganizationLoader from .models import Lead, LeadPreview, LeadGroup +from assisted_tagging.models import DraftEntry class LeadPreviewLoader(DataLoaderWithContext): @@ -103,6 +104,34 @@ def batch_load_fn(self, keys): return Promise.resolve([_map.get(key) for key in keys]) +class LeadDraftEntryCountLoader(DataLoaderWithContext): + def batch_load_fn(self, keys): + stat_qs = DraftEntry.objects\ + .filter(lead__in=keys)\ + .order_by('lead').values('lead')\ + .annotate( + discarded_draft_entry=models.functions.Coalesce( + models.Count( + 'id', + filter=models.Q(is_discarded=True) + ), + 0, + ), + undiscarded_draft_entry=models.functions.Coalesce( + models.Count( + 'id', + filter=models.Q(is_discarded=False) + ), + 0, + ), + ).values('lead_id', 'undiscarded_draft_entry', 'discarded_draft_entry') + _map = { + stat.pop('lead_id'): stat + for stat in stat_qs + } + return Promise.resolve([_map.get(key, _map) for key in keys]) + + class DataLoaders(WithContextMixin): @cached_property def lead_preview(self): @@ -127,3 +156,7 @@ def author_organizations(self): @cached_property def assessment_id(self): return LeadAssessmentIdLoader(context=self.context) + + @cached_property + def draftentry_count(self): + return LeadDraftEntryCountLoader(context=self.context) diff --git a/apps/lead/enums.py b/apps/lead/enums.py index 11b86805ce..a767fe58de 100644 --- a/apps/lead/enums.py +++ b/apps/lead/enums.py @@ -12,6 +12,9 @@ LeadPriorityEnum = convert_enum_to_graphene_enum(Lead.Priority, name='LeadPriorityEnum') LeadSourceTypeEnum = convert_enum_to_graphene_enum(Lead.SourceType, name='LeadSourceTypeEnum') LeadExtractionStatusEnum = convert_enum_to_graphene_enum(Lead.ExtractionStatus, name='LeadExtractionStatusEnum') +LeadAutoEntryExtractionTypeEnum = convert_enum_to_graphene_enum( + Lead.AutoExtractionStatus, name='LeadAutoEntryExtractionTypeEnum' +) enum_map = { get_enum_name_from_django_field(field): enum @@ -21,6 +24,7 @@ (Lead.priority, LeadPriorityEnum), (Lead.source_type, LeadSourceTypeEnum), (Lead.extraction_status, LeadExtractionStatusEnum), + (Lead.auto_entry_extraction_status, LeadAutoEntryExtractionTypeEnum), ) } diff --git a/apps/lead/migrations/0049_auto_20231121_0926.py b/apps/lead/migrations/0049_auto_20231121_0926.py new file mode 100644 index 0000000000..5957bbf49b --- /dev/null +++ b/apps/lead/migrations/0049_auto_20231121_0926.py @@ -0,0 +1,41 @@ +# Generated by Django 3.2.17 on 2023-11-21 09:26 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('lead', '0048_auto_20230228_0810'), + ] + + operations = [ + migrations.AddField( + model_name='lead', + name='auto_entry_extraction_status', + field=models.SmallIntegerField(choices=[(0, 'Pending'), (1, 'Success'), (2, 'Failed')], default=0), + ), + migrations.CreateModel( + name='ExtractedLead', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('modified_at', models.DateTimeField(auto_now=True)), + ('client_id', models.CharField(blank=True, default=None, max_length=128, null=True, unique=True)), + ('entry_extraction_classification', models.TextField()), + ('text_extraction_id', models.CharField(blank=True, max_length=50, null=True)), + ('text_extraction_status', models.IntegerField(choices=[(1, 'Initiated'), (2, 'Success'), (3, 'Failed'), (4, 'Input url process failed')], default=1)), + ('text_classification_status', models.IntegerField(choices=[(1, 'Initiated'), (2, 'Success'), (3, 'Failed'), (4, 'Input url process failed')], default=1)), + ('created_by', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='extractedlead_created', to=settings.AUTH_USER_MODEL)), + ('lead', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lead.lead')), + ('modified_by', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='extractedlead_modified', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['-created_at'], + 'abstract': False, + }, + ), + ] diff --git a/apps/lead/migrations/0049_auto_20231121_0926_squashed_0054_auto_20231218_0552.py b/apps/lead/migrations/0049_auto_20231121_0926_squashed_0054_auto_20231218_0552.py new file mode 100644 index 0000000000..ab97917c90 --- /dev/null +++ b/apps/lead/migrations/0049_auto_20231121_0926_squashed_0054_auto_20231218_0552.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2.17 on 2023-12-21 11:43 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + replaces = [('lead', '0049_auto_20231121_0926'), ('lead', '0050_delete_extractedlead'), ('lead', '0051_auto_20231128_0958'), ('lead', '0052_auto_20231130_0615'), ('lead', '0053_alter_lead_auto_entry_extraction_status'), ('lead', '0054_auto_20231218_0552')] + + dependencies = [ + ('lead', '0048_auto_20230228_0810'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='lead', + name='auto_entry_extraction_status', + field=models.SmallIntegerField(choices=[(0, 'None'), (1, 'Started'), (2, 'Pending'), (3, 'Success'), (4, 'Failed')], default=0), + ), + migrations.AddField( + model_name='leadpreview', + name='entry_extraction_id', + field=models.UUIDField(blank=True, null=True), + ), + migrations.AddField( + model_name='leadpreview', + name='text_extraction_id', + field=models.UUIDField(blank=True, null=True), + ), + ] diff --git a/apps/lead/migrations/0050_delete_extractedlead.py b/apps/lead/migrations/0050_delete_extractedlead.py new file mode 100644 index 0000000000..167a9a2851 --- /dev/null +++ b/apps/lead/migrations/0050_delete_extractedlead.py @@ -0,0 +1,16 @@ +# Generated by Django 3.2.17 on 2023-11-23 04:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('lead', '0049_auto_20231121_0926'), + ] + + operations = [ + migrations.DeleteModel( + name='ExtractedLead', + ), + ] diff --git a/apps/lead/migrations/0051_auto_20231128_0958.py b/apps/lead/migrations/0051_auto_20231128_0958.py new file mode 100644 index 0000000000..8f8bb7fb6b --- /dev/null +++ b/apps/lead/migrations/0051_auto_20231128_0958.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.17 on 2023-11-28 09:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('lead', '0050_delete_extractedlead'), + ] + + operations = [ + migrations.AddField( + model_name='leadpreview', + name='entry_extraction_id', + field=models.CharField(blank=True, max_length=30, null=True), + ), + migrations.AddField( + model_name='leadpreview', + name='text_extraction_id', + field=models.CharField(blank=True, max_length=30, null=True), + ), + migrations.AlterField( + model_name='lead', + name='auto_entry_extraction_status', + field=models.SmallIntegerField(choices=[(0, 'None'), (1, 'Pending'), (2, 'Success'), (3, 'Failed')], default=0), + ), + ] diff --git a/apps/lead/migrations/0052_auto_20231130_0615.py b/apps/lead/migrations/0052_auto_20231130_0615.py new file mode 100644 index 0000000000..848e03b6a6 --- /dev/null +++ b/apps/lead/migrations/0052_auto_20231130_0615.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.17 on 2023-11-30 06:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('lead', '0051_auto_20231128_0958'), + ] + + operations = [ + migrations.AlterField( + model_name='leadpreview', + name='entry_extraction_id', + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name='leadpreview', + name='text_extraction_id', + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/apps/lead/migrations/0053_alter_lead_auto_entry_extraction_status.py b/apps/lead/migrations/0053_alter_lead_auto_entry_extraction_status.py new file mode 100644 index 0000000000..9f1f1a114c --- /dev/null +++ b/apps/lead/migrations/0053_alter_lead_auto_entry_extraction_status.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.17 on 2023-11-30 16:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('lead', '0052_auto_20231130_0615'), + ] + + operations = [ + migrations.AlterField( + model_name='lead', + name='auto_entry_extraction_status', + field=models.SmallIntegerField(choices=[(0, 'None'), (1, 'Started'), (2, 'Pending'), (3, 'Success'), (4, 'Failed')], default=0), + ), + ] diff --git a/apps/lead/migrations/0054_auto_20231218_0552.py b/apps/lead/migrations/0054_auto_20231218_0552.py new file mode 100644 index 0000000000..72409a0663 --- /dev/null +++ b/apps/lead/migrations/0054_auto_20231218_0552.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.17 on 2023-12-18 05:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('lead', '0053_alter_lead_auto_entry_extraction_status'), + ] + + operations = [ + migrations.AlterField( + model_name='leadpreview', + name='entry_extraction_id', + field=models.UUIDField(blank=True, null=True), + ), + migrations.AlterField( + model_name='leadpreview', + name='text_extraction_id', + field=models.UUIDField(blank=True, null=True), + ), + ] diff --git a/apps/lead/models.py b/apps/lead/models.py index c17c8bd918..eb04b1fe5a 100644 --- a/apps/lead/models.py +++ b/apps/lead/models.py @@ -89,6 +89,13 @@ class ExtractionStatus(models.IntegerChoices): SUCCESS = 2, 'Success' FAILED = 3, 'Failed' + class AutoExtractionStatus(models.IntegerChoices): + NONE = 0, "None" + STARTED = 1, "Started" + PENDING = 2, 'Pending' + SUCCESS = 3, 'Success' + FAILED = 4, 'Failed' + lead_group = models.ForeignKey( LeadGroup, on_delete=models.SET_NULL, @@ -148,6 +155,8 @@ class ExtractionStatus(models.IntegerChoices): is_indexed = models.BooleanField(default=False) duplicate_leads_count = models.PositiveIntegerField(default=0) indexed_at = models.DateTimeField(null=True, blank=True) + auto_entry_extraction_status = models.SmallIntegerField( + choices=AutoExtractionStatus.choices, default=AutoExtractionStatus.NONE) def __str__(self): return '{}'.format(self.title) @@ -356,6 +365,8 @@ class ClassificationStatus(models.TextChoices): choices=ClassificationStatus.choices, default=ClassificationStatus.NONE, ) + entry_extraction_id = models.UUIDField(blank=True, null=True) # Saved when EntryExtraction is completed + text_extraction_id = models.UUIDField(blank=True, null=True) # Saved when TextExtraction is completed def __str__(self): return 'Text extracted for {}'.format(self.lead) diff --git a/apps/lead/schema.py b/apps/lead/schema.py index c20392f1f1..5d068531e3 100644 --- a/apps/lead/schema.py +++ b/apps/lead/schema.py @@ -40,6 +40,7 @@ LeadPriorityEnum, LeadSourceTypeEnum, LeadExtractionStatusEnum, + LeadAutoEntryExtractionTypeEnum, ) from .filter_set import ( LeadGQFilterSet, @@ -209,6 +210,7 @@ class Meta: 'thumbnail_width', 'word_count', 'page_count', + 'text_extraction_id' # 'classified_doc_id', # 'classification_status', ) @@ -366,6 +368,7 @@ class Meta: # For external accessible link share_view_url = graphene.String(required=True) + auto_entry_extraction_status = graphene.Field(LeadAutoEntryExtractionTypeEnum) @staticmethod def get_custom_queryset(queryset, info, **kwargs): @@ -405,6 +408,11 @@ def resolve_share_view_url(root: Lead, info, **kwargs): return Permalink.lead_share_view(root.uuid) +class DraftEntryCountByLead(graphene.ObjectType): + undiscarded_draft_entry = graphene.Int(required=False) + discarded_draft_entry = graphene.Int(required=False) + + class LeadDetailType(LeadType): class Meta: model = Lead @@ -416,6 +424,7 @@ class Meta: ) entries = graphene.List(graphene.NonNull('entry.schema.EntryType')) + draft_entry_stat = graphene.Field(DraftEntryCountByLead) @staticmethod def resolve_entries(root, info, **kwargs): @@ -423,6 +432,10 @@ def resolve_entries(root, info, **kwargs): analysis_framework=info.context.active_project.analysis_framework, ).all() + @staticmethod + def resolve_draft_entry_stat(root, info, **kwargs): + return info.context.dl.lead.draftentry_count.load(root.pk) + class LeadListType(CustomDjangoListObjectType): class Meta: diff --git a/apps/lead/tests/test_apis.py b/apps/lead/tests/test_apis.py index 13d149c2ac..1b0a21421d 100644 --- a/apps/lead/tests/test_apis.py +++ b/apps/lead/tests/test_apis.py @@ -1,5 +1,6 @@ import logging from datetime import date +import uuid from django.db.models import Q from django.core.files.uploadedfile import SimpleUploadedFile @@ -25,7 +26,7 @@ from organization.serializers import SimpleOrganizationSerializer from lead.filter_set import LeadFilterSet from lead.serializers import SimpleLeadGroupSerializer -from deepl_integration.handlers import LeadExtractionHandler +from deepl_integration.handlers import AutoAssistedTaggingDraftEntryHandler, LeadExtractionHandler from deepl_integration.serializers import DeeplServerBaseCallbackSerializer from entry.models import ( Entry, @@ -43,7 +44,7 @@ ) from user_group.models import UserGroup, GroupMembership from ary.models import Assessment -from lead.factories import LeadFactory +from lead.factories import LeadFactory, LeadPreviewFactory from unittest import mock @@ -1802,6 +1803,7 @@ def test_extractor_callback_url(self, get_file_mock, get_text_mock, index_lead_f 'total_words_count': 300, 'total_pages': 4, 'status': DeeplServerBaseCallbackSerializer.Status.FAILED.value, + 'text_extraction_id': '00431349-5879-4d59-9827-0b12491c4baa' } # After callback [Failure] @@ -1852,3 +1854,28 @@ def test_client_id_generator(self): LeadExtractionHandler.get_object_using_client_id(client_id) else: assert LeadExtractionHandler.get_object_using_client_id(client_id) == lead + + +class AutoEntryExtractionTestCase(TestCase): + def setUp(self): + super().setUp() + self.lead = LeadFactory.create() + self.lead_preview = LeadPreviewFactory.create(lead=self.lead, text_extraction_id=str(uuid.uuid1())) + + def test_entry_extraction_callback(self): + url = '/api/v1/callback/auto-assisted-tagging-draft-entry-prediction/' + self.authenticate() + data = { + "client_id": AutoAssistedTaggingDraftEntryHandler.get_client_id(self.lead), + 'entry_extraction_classification_path': 'https://server-deepl.dev.datafriendlyspace.org/media/mock_responses/entry_extraction/entry-extraction-client-6ppp.json', # noqa: E501 + 'text_extraction_id': str(self.lead_preview.text_extraction_id), + 'status': 1 + } + response = self.client.post(url, data) + self.assert_200(response) + self.lead.refresh_from_db() + self.assertEqual(self.lead.auto_entry_extraction_status, Lead.AutoExtractionStatus.SUCCESS) + self.assertEqual(str(LeadPreview.objects.get(lead=self.lead).text_extraction_id), data['text_extraction_id']) + + def test_auto_extraction_mutation(self): + pass diff --git a/apps/unified_connector/tests/test_mutation.py b/apps/unified_connector/tests/test_mutation.py index 9ee21837b3..000460172b 100644 --- a/apps/unified_connector/tests/test_mutation.py +++ b/apps/unified_connector/tests/test_mutation.py @@ -372,14 +372,14 @@ def _query_okay_check(): ( 'source-invalid', [500, 'invalid-content'], - [200, {}], + [202, {}], ConnectorSource.Status.FAILURE, [], ), ( 'all-good', [200, RELIEF_WEB_MOCK_DATA_PAGE_2_RAW], - [200, {}], + [202, {}], ConnectorSource.Status.SUCCESS, [ConnectorLead.ExtractionStatus.STARTED], ), diff --git a/deep/deepl.py b/deep/deepl.py index 25dd329f53..78e47a5ab6 100644 --- a/deep/deepl.py +++ b/deep/deepl.py @@ -8,13 +8,14 @@ class DeeplServiceEndpoint(): # DEEPL Service Endpoints (Existing/Legacy) # NOTE: This will be moved to server endpoints in near future - ASSISTED_TAGGING_TAGS_ENDPOINT = f'{DEEPL_SERVICE_DOMAIN}/vf_tags' ASSISTED_TAGGING_MODELS_ENDPOINT = f'{DEEPL_SERVICE_DOMAIN}/model_info' - ASSISTED_TAGGING_ENTRY_PREDICT_ENDPOINT = f'{DEEPL_SERVICE_DOMAIN}/entry_predict' # DEEPL Server Endpoints (New) + ASSISTED_TAGGING_TAGS_ENDPOINT = f'{DEEPL_SERVER_DOMAIN}/api/v1/nlp-tags/' DOCS_EXTRACTOR_ENDPOINT = f'{DEEPL_SERVER_DOMAIN}/api/v1/text-extraction/' ANALYSIS_TOPIC_MODEL = f'{DEEPL_SERVER_DOMAIN}/api/v1/topicmodel/' ANALYSIS_AUTOMATIC_SUMMARY = f'{DEEPL_SERVER_DOMAIN}/api/v1/summarization/' ANALYSIS_AUTOMATIC_NGRAM = f'{DEEPL_SERVER_DOMAIN}/api/v1/ngrams/' ANALYSIS_GEO = f'{DEEPL_SERVER_DOMAIN}/api/v1/geolocation/' + ASSISTED_TAGGING_ENTRY_PREDICT_ENDPOINT = f'{DEEPL_SERVER_DOMAIN}/api/v1/entry-classification/' + ENTRY_EXTRACTION_CLASSIFICATION = f'{DEEPL_SERVER_DOMAIN}/api/v1/entry-extraction-classification/' diff --git a/deep/test_files/mock_draftentry.json b/deep/test_files/mock_draftentry.json new file mode 100644 index 0000000000..cde285400d --- /dev/null +++ b/deep/test_files/mock_draftentry.json @@ -0,0 +1,567 @@ +{ + "metadata": { + "total_pages": 10, + "total_words_count": 5876, + "title": "AI in humanitarian domain", + "author": "D Harvey", + "keywords": [ + "health", + "medical treatments" + ], + "format": "PDF 1.4" + }, + "blocks": [ + { + "type": "text", + "page": 1, + "x0": 0, + "y0": 63.453, + "x1": 545.23, + "y1": 106.23, + "text": "The 2021 Gu rainy season performance varied across Somalia with many places recording average to below average rainfall (Maps 1 & 2, and Annex I). The seasonal rains which started in late April lasted for three weeks and came to an early end during the first week of May 2021. During the three weeks of rainfall, some places recorded heavy rains that led to flash floods in the northern parts of the country. The southern regions recorded below normal seasonal rains, leaving many places under water stress. This follows another poor rainfall performance during the 2020 Deyr (October- December) season which led to moderate drought conditions this year that lasted till late April", + "textOrder": 1, + "textCrop": [ + 36, + 135.47, + 321.3, + 295.97 + ], + "relevant": true, + "classification": { + "model_preds": [ + { + "tags": { + "1": { + "101": { + "prediction": 0.0000270270529, + "threshold": 0.14, + "is_selected": false + }, + "102": { + "prediction": 2.791275697595933, + "threshold": 0.17, + "is_selected": true + }, + "103": { + "prediction": 0.000845505346661, + "threshold": 0.1, + "is_selected": false + }, + "104": { + "prediction": 0.001551844096476, + "threshold": 0.14, + "is_selected": false + }, + "105": { + "prediction": 0.000610130882706, + "threshold": 0.18, + "is_selected": false + }, + "106": { + "prediction": 0.021222406732185, + "threshold": 0.14, + "is_selected": false + }, + "107": { + "prediction": 0.000047710691433, + "threshold": 0.1, + "is_selected": false + }, + "108": { + "prediction": 0.000005902628667, + "threshold": 0.12, + "is_selected": false + }, + "109": { + "prediction": 5.845728317896525, + "threshold": 0.15, + "is_selected": true + }, + "110": { + "prediction": 0.000993687879398, + "threshold": 0.18, + "is_selected": false + }, + "111": { + "prediction": 0.000130282686379, + "threshold": 0.14, + "is_selected": false + } + }, + "2": { + "201": { + "prediction": 0.001077209547956, + "threshold": 0.17, + "is_selected": false + }, + "202": { + "prediction": 0.002082403516397, + "threshold": 0.15, + "is_selected": false + }, + "203": { + "prediction": 0.027398668074359, + "threshold": 0.24, + "is_selected": false + }, + "204": { + "prediction": 0.000344154328299, + "threshold": 0.14, + "is_selected": false + }, + "205": { + "prediction": 0.008931630191968, + "threshold": 0.47, + "is_selected": false + }, + "206": { + "prediction": 1.561535708606243, + "threshold": 0.16, + "is_selected": true + }, + "207": { + "prediction": 0.008022336987779, + "threshold": 0.22, + "is_selected": false + }, + "208": { + "prediction": 0.000339151683008, + "threshold": 0.21, + "is_selected": false + }, + "209": { + "prediction": 0.664219930768013, + "threshold": 0.05, + "is_selected": false + }, + "210": { + "prediction": 0.070768408477306, + "threshold": 0.24, + "is_selected": false + }, + "212": { + "prediction": 0.002422974061882, + "threshold": 0.31, + "is_selected": false + }, + "213": { + "prediction": 0.000046979557038, + "threshold": 0.26, + "is_selected": false + }, + "214": { + "prediction": 0.000070475855157, + "threshold": 0.09, + "is_selected": false + }, + "215": { + "prediction": 0.000008547227329, + "threshold": 0.15, + "is_selected": false + }, + "216": { + "prediction": 0.000167800135387, + "threshold": 0.13, + "is_selected": false + }, + "217": { + "prediction": 0.000016116082691, + "threshold": 0.04, + "is_selected": false + }, + "218": { + "prediction": 0.00002616270649, + "threshold": 0.09, + "is_selected": false + }, + "219": { + "prediction": 0.000166147779405, + "threshold": 0.13, + "is_selected": false + }, + "220": { + "prediction": 0.000002293435324, + "threshold": 0.22, + "is_selected": false + }, + "221": { + "prediction": 2.3751352e-7, + "threshold": 0.16, + "is_selected": false + }, + "222": { + "prediction": 0.000008183459954, + "threshold": 0.16, + "is_selected": false + }, + "223": { + "prediction": 0.000764200214892, + "threshold": 0.09, + "is_selected": false + }, + "224": { + "prediction": 7.88740062e-7, + "threshold": 0.21, + "is_selected": false + }, + "225": { + "prediction": 0.000002737477267, + "threshold": 0.04, + "is_selected": false + }, + "226": { + "prediction": 3.95147303e-7, + "threshold": 0.09, + "is_selected": false + }, + "227": { + "prediction": 0.000015625468157, + "threshold": 0.07, + "is_selected": false + }, + "228": { + "prediction": 0.000017889078663, + "threshold": 0.72, + "is_selected": false + }, + "229": { + "prediction": 3.389243e-9, + "threshold": 0.55, + "is_selected": false + }, + "230": { + "prediction": 0.000016569508455, + "threshold": 0.61, + "is_selected": false + }, + "231": { + "prediction": 0.000004143511584, + "threshold": 0.3, + "is_selected": false + }, + "232": { + "prediction": 0.000640358295008, + "threshold": 0.23, + "is_selected": false + }, + "233": { + "prediction": 0.000006404845789, + "threshold": 0.31, + "is_selected": false + }, + "234": { + "prediction": 0.000074884925338, + "threshold": 0.39, + "is_selected": false + } + }, + "3": { + "301": { + "prediction": 0.000083330627376, + "threshold": 0.01, + "is_selected": false + }, + "302": { + "prediction": 0.011204658287831, + "threshold": 0.11, + "is_selected": false + }, + "303": { + "prediction": 0.000861139989483, + "threshold": 0.38, + "is_selected": false + }, + "304": { + "prediction": 0.000009533644629, + "threshold": 0.01, + "is_selected": false + }, + "305": { + "prediction": 0.010194102137843, + "threshold": 0.17, + "is_selected": false + }, + "306": { + "prediction": 0.000047473428519, + "threshold": 0.15, + "is_selected": false + }, + "307": { + "prediction": 0.00275926431641, + "threshold": 0.09, + "is_selected": false + }, + "308": { + "prediction": 0.006035644596872, + "threshold": 0.13, + "is_selected": false + }, + "309": { + "prediction": 0.000018762974768, + "threshold": 0.07, + "is_selected": false + }, + "310": { + "prediction": 0.16048023244366, + "threshold": 0.16, + "is_selected": true + }, + "311": { + "prediction": 0.001379056581451, + "threshold": 0.15, + "is_selected": false + }, + "312": { + "prediction": 0.144955087453127, + "threshold": 0.2, + "is_selected": false + }, + "313": { + "prediction": 0.042628173832782, + "threshold": 0.16, + "is_selected": false + }, + "314": { + "prediction": 0.000043664708755, + "threshold": 0.05, + "is_selected": false + }, + "315": { + "prediction": 0.000097360397275, + "threshold": 0.45, + "is_selected": false + }, + "316": { + "prediction": 0.000012243420618, + "threshold": 0.06, + "is_selected": false + }, + "317": { + "prediction": 0.000005113670909, + "threshold": 0.28, + "is_selected": false + }, + "318": { + "prediction": 0.000393391634973, + "threshold": 0.13, + "is_selected": false + } + }, + "4": { + "401": { + "prediction": 1.17259055e-7, + "threshold": 0.29, + "is_selected": false + }, + "402": { + "prediction": 0.000013744229364, + "threshold": 0.45, + "is_selected": false + }, + "403": { + "prediction": 4.87375621e-7, + "threshold": 0.03, + "is_selected": false + }, + "404": { + "prediction": 1.85885169e-7, + "threshold": 0.34, + "is_selected": false + }, + "405": { + "prediction": 3.05366841e-7, + "threshold": 0.37, + "is_selected": false + }, + "406": { + "prediction": 0.000034889759263, + "threshold": 0.25, + "is_selected": false + }, + "407": { + "prediction": 0.000001803972996, + "threshold": 0.07, + "is_selected": false + }, + "408": { + "prediction": 0.001109504095935, + "threshold": 0.11, + "is_selected": false + }, + "409": { + "prediction": 2.59159425e-7, + "threshold": 0.43, + "is_selected": false + }, + "410": { + "prediction": 1.45469337e-7, + "threshold": 0.23, + "is_selected": false + }, + "411": { + "prediction": 0.000005189525136, + "threshold": 0.06, + "is_selected": false + }, + "412": { + "prediction": 0.000002016342806, + "threshold": 0.36, + "is_selected": false + } + }, + "5": { + "501": { + "prediction": 0.000025967284374, + "threshold": 0.45, + "is_selected": false + }, + "502": { + "prediction": 0.000565126356378, + "threshold": 0.48, + "is_selected": false + } + }, + "6": { + "601": { + "prediction": 0.000177106418657, + "threshold": 0.06, + "is_selected": false + }, + "602": { + "prediction": 0.00055463691145, + "threshold": 0.48, + "is_selected": false + }, + "603": { + "prediction": 0.000022633564774, + "threshold": 0.34, + "is_selected": false + }, + "604": { + "prediction": 0.001842333040258, + "threshold": 0.16, + "is_selected": false + } + }, + "7": { + "701": { + "prediction": 0.000903384244777, + "threshold": 0.27, + "is_selected": false + }, + "702": { + "prediction": 0.001251186238898, + "threshold": 0.11, + "is_selected": false + }, + "703": { + "prediction": 0.000834142483654, + "threshold": 0.05, + "is_selected": false + }, + "704": { + "prediction": 0.000382219089564, + "threshold": 0.24, + "is_selected": false + }, + "705": { + "prediction": 0.001979890172758, + "threshold": 0.12, + "is_selected": true + } + }, + "8": { + "801": { + "prediction": 0.000014654744629, + "threshold": 0.66, + "is_selected": false + }, + "802": { + "prediction": 0.000044733506002, + "threshold": 0.3, + "is_selected": false + }, + "803": { + "prediction": 0.001036487083184, + "threshold": 0.36, + "is_selected": false + }, + "804": { + "prediction": 0.000707629901033, + "threshold": 0.23, + "is_selected": false + }, + "805": { + "prediction": 0.00003381500674, + "threshold": 0.58, + "is_selected": false + }, + "806": { + "prediction": 0.702028969923655, + "threshold": 0.3, + "is_selected": false + } + }, + "9": { + "902": { + "prediction": -1, + "threshold": -1, + "is_selected": false + }, + "903": { + "prediction": -1, + "threshold": -1, + "is_selected": false + }, + "904": { + "prediction": -1, + "threshold": -1, + "is_selected": false + }, + "905": { + "prediction": -1, + "threshold": -1, + "is_selected": false + }, + "906": { + "prediction": -1, + "threshold": -1, + "is_selected": false + }, + "907": { + "prediction": -1, + "threshold": -1, + "is_selected": false + } + } + }, + "prediction_status": "1", + "model_info": { + "id": "all_tags_model", + "version": "1.0.0" + } + }, + { + "model_info": { + "id": "geolocation", + "version": "1.0.0" + }, + "values": [], + "prediction_status": 1 + }, + { + "model_info": { + "id": "reliability", + "version": "1.0.0" + }, + "tags": {}, + "prediction_status": 0 + } + ] + } + } + ], + "client_id": "Mzc3Mg-bxc2ae-ab84e5577710374c9044d5527a813c7f", + "text_extraction_id": "Eei55y-ees2ae-ab77e5589110334c9077d5527a813c7f", + "text_extraction_status": 2 +} diff --git a/deep/urls.py b/deep/urls.py index 5f45439f0d..747ad29892 100644 --- a/deep/urls.py +++ b/deep/urls.py @@ -149,6 +149,7 @@ ) from deepl_integration.views import ( AssistedTaggingDraftEntryPredictionCallbackView, + AutoTaggingDraftEntryPredictionCallbackView, LeadExtractCallbackView, UnifiedConnectorLeadExtractCallbackView, AnalysisTopicModelCallbackView, @@ -566,6 +567,11 @@ def get_api_path(path): AssistedTaggingDraftEntryPredictionCallbackView.as_view(), name='assisted_tagging_draft_entry_prediction_callback', ), + re_path( + get_api_path(r'callback/auto-assisted-tagging-draft-entry-prediction/$'), + AutoTaggingDraftEntryPredictionCallbackView.as_view(), + name='auto-assisted_tagging_draft_entry_prediction_callback', + ), re_path( get_api_path(r'callback/analysis-topic-model/$'), diff --git a/schema.graphql b/schema.graphql index d48a3e7f85..73913f8d9a 100644 --- a/schema.graphql +++ b/schema.graphql @@ -974,6 +974,7 @@ type AppEnumCollection { LeadPriority: [AppEnumCollectionLeadPriority!] LeadSourceType: [AppEnumCollectionLeadSourceType!] LeadExtractionStatus: [AppEnumCollectionLeadExtractionStatus!] + LeadAutoEntryExtractionStatus: [AppEnumCollectionLeadAutoEntryExtractionStatus!] EntryEntryType: [AppEnumCollectionEntryEntryType!] ExportFormat: [AppEnumCollectionExportFormat!] ExportStatus: [AppEnumCollectionExportStatus!] @@ -1005,6 +1006,7 @@ type AppEnumCollection { ConnectorLeadExtractionStatus: [AppEnumCollectionConnectorLeadExtractionStatus!] DraftEntryPredictionStatus: [AppEnumCollectionDraftEntryPredictionStatus!] AssistedTaggingPredictionDataType: [AppEnumCollectionAssistedTaggingPredictionDataType!] + DraftEntryType: [AppEnumCollectionDraftEntryType!] UnusedAssessmentMethodologyProtectionInfo: [AppEnumCollectionUnusedAssessmentMethodologyProtectionInfo!] } @@ -1110,6 +1112,12 @@ type AppEnumCollectionDraftEntryPredictionStatus { description: String } +type AppEnumCollectionDraftEntryType { + enum: DraftEntryTypeEnum! + label: String! + description: String +} + type AppEnumCollectionEntryEntryType { enum: EntryTagTypeEnum! label: String! @@ -1194,6 +1202,12 @@ type AppEnumCollectionGroupMembershipRole { description: String } +type AppEnumCollectionLeadAutoEntryExtractionStatus { + enum: LeadAutoEntryExtractionTypeEnum! + label: String! + description: String +} + type AppEnumCollectionLeadConfidentiality { enum: LeadConfidentialityEnum! label: String! @@ -1383,6 +1397,8 @@ type AssistedTaggingMutationType { wrongPredictionReviewCreate(data: WrongPredictionReviewInputType!): CreateWrongPredictionReview missingPredictionReviewDelete(id: ID!): DeleteMissingPredictionReview wrongPredictionReviewDelete(id: ID!): DeleteWrongPredictionReview + triggerAutoDraftEntry(data: TriggerAutoDraftEntryInputType!): TriggerAutoDraftEntry + updateDraftEntry(data: UpdateDraftEntryInputType!, id: ID!): UpdateDraftEntry } enum AssistedTaggingPredictionDataTypeEnum { @@ -1408,6 +1424,7 @@ type AssistedTaggingPredictionType { type AssistedTaggingQueryType { draftEntry(id: ID!): DraftEntryType + draftEntries(lead: ID, draftEntryTypes: [DraftEntryTypeEnum!], isDiscarded: Boolean, page: Int = 1, pageSize: Int): DraftEntryListType } type AssistedTaggingRootQueryType { @@ -1935,11 +1952,23 @@ type DjangoDebugSQL { encoding: String } +type DraftEntryCountByLead { + undiscardedDraftEntry: Int + discardedDraftEntry: Int +} + input DraftEntryInputType { lead: ID! excerpt: String! } +type DraftEntryListType { + results: [DraftEntryType!] + totalCount: Int + page: Int + pageSize: Int +} + enum DraftEntryPredictionStatusEnum { PENDING STARTED @@ -1958,6 +1987,11 @@ type DraftEntryType { relatedGeoareas: [ProjectGeoAreaType!] } +enum DraftEntryTypeEnum { + AUTO + MANUAL +} + input EMMEntityInputType { name: String! } @@ -2644,6 +2678,14 @@ type JwtTokenType { expiresIn: String } +enum LeadAutoEntryExtractionTypeEnum { + NONE + STARTED + PENDING + SUCCESS + FAILED +} + enum LeadConfidentialityEnum { UNPROTECTED RESTRICTED @@ -2696,7 +2738,9 @@ type LeadDetailType { filteredEntriesCount: Int duplicateLeadsCount: Int shareViewUrl: String! + autoEntryExtractionStatus: LeadAutoEntryExtractionTypeEnum entries: [EntryType!] + draftEntryStat: DraftEntryCountByLead } input LeadEMMTriggerInputType { @@ -2822,6 +2866,7 @@ type LeadPreviewType { thumbnailWidth: Int wordCount: Int pageCount: Int + textExtractionId: UUID } enum LeadPriorityEnum { @@ -2883,6 +2928,7 @@ type LeadType { filteredEntriesCount: Int duplicateLeadsCount: Int shareViewUrl: String! + autoEntryExtractionStatus: LeadAutoEntryExtractionTypeEnum } input LeadsFilterDataInputType { @@ -3941,6 +3987,15 @@ type TriggerAnalysisTopicModel { result: AnalysisTopicModelType } +type TriggerAutoDraftEntry { + errors: [GenericScalar!] + ok: Boolean +} + +input TriggerAutoDraftEntryInputType { + lead: ID! +} + type TriggerUnifiedConnector { errors: [GenericScalar!] ok: Boolean @@ -4040,6 +4095,17 @@ type UpdateConnectorSourceLead { result: ConnectorSourceLeadType } +type UpdateDraftEntry { + errors: [GenericScalar!] + ok: Boolean + result: DraftEntryType +} + +input UpdateDraftEntryInputType { + lead: ID! + isDiscarded: Boolean +} + type UpdateEntry { errors: [GenericScalar!] ok: Boolean