Source code for search.controllers.simple

"""
Handle requests to support the simple search feature.

The primary entrypoint to this module is :func:`.search`, which handles
GET requests to the base search endpoint. It uses :class:`.SimpleSearchForm`
to generate form HTML, validate request parameters, and produce informative
error messages for the user.
"""

from typing import Tuple, Dict, Any, Optional, List

from werkzeug.exceptions import InternalServerError, NotFound, BadRequest
from werkzeug import MultiDict, ImmutableMultiDict
from flask import url_for

from arxiv import status, identifier, taxonomy

from arxiv.base import logging
from search.services import index, fulltext, metadata
from search.domain import Query, SimpleQuery, asdict, Classification, \
    ClassificationList
from search.controllers.util import paginate, catch_underscore_syntax

from .forms import SimpleSearchForm
# from search.routes.ui import external_url_builder

logger = logging.getLogger(__name__)

Response = Tuple[Dict[str, Any], int, Dict[str, Any]]





[docs]def retrieve_document(document_id: str) -> Response: """ Retrieve an arXiv paper by ID. Parameters ---------- document_id : str arXiv identifier for the paper. Returns ------- dict Metadata about the paper. int HTTP status code. dict Headers to add to the response. Raises ------ InternalServerError Encountered error in search query. NotFound No such document """ try: result = index.get_document(document_id) except index.IndexConnectionError as e: # There was a (hopefully transient) connection problem. Either # this will clear up relatively quickly (next request), or # there is a more serious outage. logger.error('IndexConnectionError: %s', e) raise InternalServerError( "There was a problem connecting to the search index. This is " "quite likely a transient issue, so please try your search " "again. If this problem persists, please report it to " "help@arxiv.org." ) from e except index.QueryError as e: # Base exception routers should pick this up and show bug page. logger.error('QueryError: %s', e) raise InternalServerError( "There was a problem executing your query. Please try your " "search again. If this problem persists, please report it to " "help@arxiv.org." ) from e except index.DocumentNotFound as e: logger.error('DocumentNotFound: %s', e) raise NotFound(f"Could not find a paper with id {document_id}") from e return {'document': result}, status.HTTP_200_OK, {}
def _update_with_archives(q: SimpleQuery, archives: List[str]) -> SimpleQuery: """ Search within a group or archive. Parameters ---------- q : :class:`SimpleQuery` groups_or_archives : str Returns ------- :class:`SimpleQuery` """ logger.debug('Search within %s', archives) q.classification = ClassificationList([ Classification(archive={'id': archive}) # type: ignore for archive in archives ]) return q def _query_from_form(form: SimpleSearchForm) -> SimpleQuery: """ Generate a :class:`.SimpleQuery` from valid :class:`.SimpleSearchForm`. Parameters ---------- form : :class:`.SimpleSearchForm` Presumed to be filled and valid. Returns ------- :class:`.SimpleQuery` """ q = SimpleQuery() q.search_field = form.searchtype.data q.value = form.query.data q.hide_abstracts = form.abstracts.data == form.HIDE_ABSTRACTS order = form.order.data if order and order != 'None': q.order = order return q