Skip to content

Commit

Permalink
Merge pull request #748 from petridishdev/feature/v4-search-autocomplete
Browse files Browse the repository at this point in the history
feat: temporarily re-introduce v4/search/autocomplete
  • Loading branch information
esune authored Jun 7, 2023
2 parents 5f2f098 + 3aecb65 commit dd2a7fb
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 18 deletions.
14 changes: 14 additions & 0 deletions server/vcr-server/api/v4/search/filters/autocomplete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# DEPRECATED: this should not be used in new code and will be removed imminently

from api.v3.search_filters import AutocompleteFilter as V3AutocompleteFilter
from api.v3.search_filters import get_autocomplete_builder


class AutocompleteFilter(V3AutocompleteFilter):
"""
Apply name autocomplete filter to credential search
"""

query_builder_class = get_autocomplete_builder(
("name_text", "address_civic_address", "topic_source_id", "topic_name")
)
28 changes: 28 additions & 0 deletions server/vcr-server/api/v4/serializers/search/autocomplete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# DEPRECATED: this should not be used in new code and will be removed imminently

from rest_framework.serializers import SerializerMethodField

from api.v3.indexes.Topic import TopicIndex

from api.v2.serializers.rest import TopicSerializer

from api.v3.serializers.search import (
TopicAutocompleteSerializer as V3TopicAutocompleteSerializer,
)


class TopicAutocompleteSerializer(V3TopicAutocompleteSerializer):
names = SerializerMethodField()

@staticmethod
def get_names(obj):
return [
name.text
for name in obj.object.get_active_names()
if name.type == "entity_name"
]

class Meta(TopicSerializer.Meta):
index_classes = [TopicIndex]
fields = ("id", "type", "sub_type", "value", "score", "topic_source_id",
"topic_type", "credential_id", "credential_type", "names",)
22 changes: 8 additions & 14 deletions server/vcr-server/api/v4/serializers/search/topic.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import logging
from collections import OrderedDict

from rest_framework.serializers import BooleanField, CharField, DateTimeField, IntegerField, SerializerMethodField
from drf_haystack.serializers import HaystackSerializer, HaystackFacetSerializer
from drf_haystack.serializers import HaystackSerializer

from api.v2.models.Address import Address
from api.v2.models.Credential import Credential
from api.v2.models.CredentialType import CredentialType
from api.v2.models.Issuer import Issuer
from api.v2.models.Name import Name
from api.v2.models.Topic import Topic

from api.v2.serializers.rest import (
AddressSerializer,
CredentialSerializer,
CredentialSetSerializer,
CredentialTypeSerializer,
NameSerializer,
TopicSerializer,
TopicAttributeSerializer,
)
from api.v2.serializers.search import (
Expand All @@ -28,10 +21,10 @@


facet_filter_display_map = {
'topic_category': 'category',
'topic_issuer_id': 'issuer_id',
'topic_type_id': 'type_id',
'topic_credential_type_id': 'credential_type_id',
"topic_category": "category",
"topic_issuer_id": "issuer_id",
"topic_type_id": "type_id",
"topic_credential_type_id": "credential_type_id",
}


Expand Down Expand Up @@ -88,7 +81,8 @@ class Meta:
fields = ("id", "source_id", "type", "names", "addresses", "attributes", "credential_set",
"credential_type", "inactive", "revoked", "effective_date", "revoked_date")
# ExactFilter fields
exact_fields = ("topic_issuer_id", "topic_type_id", "topic_credential_type_id")
exact_fields = ("topic_issuer_id", "topic_type_id",
"topic_credential_type_id")
# StatusFilter fields
status_fields = {"topic_inactive": "false", "topic_revoked": "false"}
# HaystackFilter fields
Expand Down Expand Up @@ -125,7 +119,7 @@ def format_facet_text(self, field_name, facets):
if len(rows):
text = {
field_name: {
str(row['id']): row[field_selector] for row in rows.values()
str(row["id"]): row[field_selector] for row in rows.values()
}
}

Expand Down
16 changes: 12 additions & 4 deletions server/vcr-server/api/v4/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from api.v4.views.search import (
topic as search_topic,
credential as search_credential,
fuzzy as search_fuzzy
fuzzy as search_fuzzy,
# DEPRECATED: this should not be used in new code and will be removed imminently
autocomplete as search_autocomplete,
)
from api.v4.views.rest import credential_type, issuer, topic, schemas
from api.v4.views.misc.contact import send_contact
Expand All @@ -34,13 +36,18 @@

router = SimpleRouter(trailing_slash=False)

router.register(r"credential-type", credential_type.RestView, "Credential Type")
router.register(r"credential-type",
credential_type.RestView, "Credential Type")
router.register(r"issuer", issuer.RestView, "Issuer")
router.register(r"schemas", schemas.RestView)
router.register(r"topic", topic.RestView)
router.register(r"search/credential", search_credential.SearchView, "Credential Search")
router.register(r"search/credential",
search_credential.SearchView, "Credential Search")
router.register(r"search/topic", search_topic.SearchView, "Topic Search")
router.register(r"search/fuzzy", search_fuzzy.SearchView, "Fuzzy Search")
# DEPRECATED: this should not be used in new code and will be removed imminently
router.register(r"search/autocomplete",
search_autocomplete.SearchView, "Aggregate Autocomplete")

# Misc endpoints
miscPatterns = [
Expand All @@ -52,4 +59,5 @@
path("", schema_view.with_ui("swagger", cache_timeout=None), name="api-docs")
]

urlpatterns = format_suffix_patterns(router.urls) + miscPatterns + swaggerPatterns
urlpatterns = format_suffix_patterns(
router.urls) + miscPatterns + swaggerPatterns
105 changes: 105 additions & 0 deletions server/vcr-server/api/v4/views/search/autocomplete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# DEPRECATED: this should not be used in new code and will be removed imminently

import logging

from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from drf_haystack.serializers import HaystackSerializer

from api.v3.views.search import (
AggregateAutocompleteView,
aggregate_autocomplete_swagger_params as swagger_params,
)
from api.v3.serializers.search import (
AddressAutocompleteSerializer,
NameAutocompleteSerializer,
# TODO: create a v4 version of this serializer
TopicAutocompleteSerializer,
)
from api.v3.search_filters import StatusFilter as AutocompleteStatusFilter
from api.v4.search.filters.autocomplete import AutocompleteFilter
from api.v4.search.filters.topic import (
TopicCategoryFilter as AutocompleteCategoryFilter,
TopicExactFilter as AutocompleteExactFilter,
)
from api.v3.indexes import (
Address as AddressIndex,
Name as NameIndex,
Topic as TopicIndex,
)

LOGGER = logging.getLogger(__name__)

_swagger_params = [
openapi.Parameter(
"category",
openapi.IN_QUERY,
description="Filter by Credential Category. The category name and value should be joined by '::'",
type=openapi.TYPE_STRING,
),
openapi.Parameter(
"type_id",
openapi.IN_QUERY,
description="Filter by Credential Type ID of the Topic",
type=openapi.TYPE_STRING,
),
openapi.Parameter(
"issuer_id",
openapi.IN_QUERY,
description="Filter by Issuer ID of the Topic",
type=openapi.TYPE_STRING,
),
openapi.Parameter(
"credential_type_id",
openapi.IN_QUERY,
description="Filter by Credential Type ID of any credentials owned by the Topic",
type=openapi.TYPE_STRING,
),
# Put additional parameters here
] + list(swagger_params)


class AggregateAutocompleteSerializer(HaystackSerializer):
class Meta:
serializers = {
AddressIndex: AddressAutocompleteSerializer,
NameIndex: NameAutocompleteSerializer,
TopicIndex: TopicAutocompleteSerializer,
}

filter_fields_map = {
"category": ("topic_category",),
"issuer_id": ("topic_issuer_id"),
"type_id": ("topic_type_id"),
"credential_type_id": ("topic_credential_type_id"),
"inactive": (
"address_credential_inactive",
"name_credential_inactive",
"topic_all_credentials_inactive",
),
"revoked": (
"address_credential_revoked",
"name_credential_revoked",
"topic_all_credentials_revoked",
),
}


class SearchView(AggregateAutocompleteView):
"""
Return autocomplete results for a query string
"""

@swagger_auto_schema(
manual_parameters=_swagger_params,
responses={200: AggregateAutocompleteSerializer(many=True)},
)
def list(self, *args, **kwargs):
return super(SearchView, self).list(*args, **kwargs)

filter_backends = (
AutocompleteFilter,
AutocompleteStatusFilter,
AutocompleteCategoryFilter,
AutocompleteExactFilter,
)

0 comments on commit dd2a7fb

Please sign in to comment.