From 423f1d3f11dab62b0bf650871ca883520226c52f Mon Sep 17 00:00:00 2001 From: Aayush Jain Date: Wed, 18 Aug 2021 02:51:17 +0530 Subject: [PATCH 1/5] add autosuggest api --- here_location_services/autosuggest_api.py | 85 +++++++++++++++++++ .../config/autosuggest_config.py | 50 +++++++++++ here_location_services/ls.py | 56 ++++++++++++ here_location_services/responses.py | 13 +++ tests/conftest.py | 8 ++ tests/test_ls.py | 27 ++++++ tests/test_ls_apis.py | 8 ++ 7 files changed, 247 insertions(+) create mode 100644 here_location_services/autosuggest_api.py create mode 100644 here_location_services/config/autosuggest_config.py diff --git a/here_location_services/autosuggest_api.py b/here_location_services/autosuggest_api.py new file mode 100644 index 0000000..b36f8bb --- /dev/null +++ b/here_location_services/autosuggest_api.py @@ -0,0 +1,85 @@ +# Copyright (C) 2019-2021 HERE Europe B.V. +# SPDX-License-Identifier: Apache-2.0 + +"""This module contains classes for accessing `HERE Autosuggest API `_. +""" # noqa E501 + +from typing import Dict, List, Optional + +from here_location_services.config.autosuggest_config import SearchBox, SearchCircle +from here_location_services.platform.auth import Auth + +from .apis import Api +from .exceptions import ApiError + + +class AutosuggestApi(Api): + """A class for accessing HERE Autosuggest API.""" + + def __init__( + self, + api_key: Optional[str] = None, + auth: Optional[Auth] = None, + proxies: Optional[dict] = None, + country: str = "row", + ): + super().__init__(api_key, auth=auth, proxies=proxies, country=country) + self._base_url = f"https://autosuggest.search.{self._get_url_string()}" + + def get_autosuggest( + self, + q: str, + at: Optional[List] = None, + search_in_circle: Optional[SearchCircle] = None, + search_in_box: Optional[SearchBox] = None, + in_country: Optional[List] = None, + limit: Optional[int] = None, + terms_limit: Optional[int] = None, + lang: Optional[List] = None, + political_view: Optional[str] = None, + show: Optional[str] = None, + ): + """Calculate route between two endpoints. + + See further information `here _`. + + :param transport_mode: A string to represent mode of transport. + + """ # noqa E501 + path = "v1/autosuggest" + url = f"{self._base_url}/{path}" + params: Dict[str, str] = { + "q": q, + } + if at: + params["at"] = ",".join([str(i) for i in at]) + if in_country: + params["in[countryCode]"] = ",".join([str(i) for i in in_country]) + if search_in_circle: + params["in[circle]"] = search_in_circle.lat + "," + search_in_circle.lng + params["in[r]"] = str(search_in_circle.radius) + if limit: + params["limit"] = str(limit) + if terms_limit: + params["termsLimit"] = str(terms_limit) + if lang: + params["lang"] = ",".join([str(i) for i in lang]) + if political_view: + params["politicalView"] = political_view + if show: + params["show"] = show + if search_in_box: + params["in[bbox]"] = ( + search_in_box.west + + "," + + search_in_box.south + + "," + + search_in_box.east + + "," + + search_in_box.north + ) + resp = self.get(url, params=params, proxies=self.proxies) + if resp.status_code == 200: + return resp + else: + raise ApiError(resp) diff --git a/here_location_services/config/autosuggest_config.py b/here_location_services/config/autosuggest_config.py new file mode 100644 index 0000000..d381850 --- /dev/null +++ b/here_location_services/config/autosuggest_config.py @@ -0,0 +1,50 @@ +# Copyright (C) 2019-2021 HERE Europe B.V. +# SPDX-License-Identifier: Apache-2.0 + +"""This module defines all the configs which will be required as inputs to autosuggest API.""" + +from .base_config import Bunch + + +class SearchCircle: + """A class to define ``SearchCircle`` + + Results will be returned if they are located within the specified circular area defined by its center and radius(in meters). + """ + + def __init__(self, lat: str, lng: str, radius: int): + self.lat = lat + self.lng = lng + self.radius = radius + + +class SearchBox: + """A class to define ``SearchBox`` + + Results will be returned if they are located within the specified rectangular area defined by its west longitude, south latitude, east longitude, north latitude + """ + + def __init__(self, westLng: str, southLat: str, eastLng: str, northLat: str): + self.west = westLng + self.south = southLat + self.east = eastLng + self.north = northLat + + +class PoliticalView(Bunch): + """A Class to define constant values for political view + + ``RUS``: + expressing the Russian view on Crimea + + ``SRB``: + expressing the Serbian view on Kosovo, Vukovar and Sarengrad Islands + + ``MAR``: + expressing the Moroccan view on Western Sahara + """ + + +#: Use this config for political_view of Autosuggest API. +#: Example: for ``RUS`` political_view use ``POLITICAL_VIEW.RUS``. +POLITICAL_VIEW = PoliticalView(**{"RUS": "RUS", "SRB": "SRB", "MAR": "MAR", }) diff --git a/here_location_services/ls.py b/here_location_services/ls.py index e4ffd24..5b9bd1d 100644 --- a/here_location_services/ls.py +++ b/here_location_services/ls.py @@ -15,6 +15,8 @@ from here_location_services.platform.auth import Auth from here_location_services.platform.credentials import PlatformCredentials +from .autosuggest_api import AutosuggestApi +from .config.autosuggest_config import SearchBox, SearchCircle from .config.base_config import PlaceOptions, Truck, WayPointOptions from .config.matrix_routing_config import ( AutoCircleRegion, @@ -29,6 +31,7 @@ from .isoline_routing_api import IsolineRoutingApi from .matrix_routing_api import MatrixRoutingApi from .responses import ( + AutosuggestResponse, BrowseResponse, DiscoverResponse, GeocoderResponse, @@ -85,6 +88,12 @@ def __init__( self.matrix_routing_api = MatrixRoutingApi( api_key=api_key, auth=self.auth, proxies=proxies, country=country ) + self.autosuggest_api = AutosuggestApi( + api_key=api_key, + auth=self.auth, + proxies=proxies, + country=country, + ) def geocode(self, query: str, limit: int = 20, lang: str = "en-US") -> GeocoderResponse: """Calculate coordinates as result of geocoding for the given ``query``. @@ -233,6 +242,53 @@ def calculate_isoline( raise ValueError("Isolines could not be calculated.") return response + def autosuggest( + self, + q: str, + at: Optional[List] = None, + search_in_circle: Optional[SearchCircle] = None, + search_in_box: Optional[SearchBox] = None, + in_country: Optional[List] = None, + limit: Optional[int] = None, + terms_limit: Optional[int] = None, + lang: Optional[List] = None, + political_view: Optional[str] = None, + show: Optional[str] = None, + ) -> AutosuggestResponse: + """Calculate isoline routing. + + Request a polyline that connects the endpoints of all routes + leaving from one defined center with either a specified length + or specified travel time. + + + """ + + if search_in_circle and search_in_box and at: + raise ValueError( + "`search_in_circle` and `search_in_box` and `at` can not be provided together." + ) + if search_in_circle is None and search_in_box is None and at is None: + raise ValueError( + "please provide either `search_in_circle` or `search_in_box` or `at`." + ) + + resp = self.autosuggest_api.get_autosuggest( + q=q, + at=at, + search_in_box=search_in_box, + search_in_circle=search_in_circle, + in_country=in_country, + limit=limit, + terms_limit=terms_limit, + lang=lang, + political_view=political_view, + show=show, + ) + response = AutosuggestResponse.new(resp.json()) + + return response + def discover( self, query: str, diff --git a/here_location_services/responses.py b/here_location_services/responses.py index 040e031..ad07174 100644 --- a/here_location_services/responses.py +++ b/here_location_services/responses.py @@ -180,3 +180,16 @@ def to_travel_times_matrix(self): distances[i : i + dest_count] for i in range(0, len(distances), dest_count) ] return DataFrame(nested_distances, columns=range(dest_count)) + + +class AutosuggestResponse(ApiResponse): + """A class representing the Reverse Isoline routing API response data.""" + + def __init__(self, **kwargs): + super().__init__() + self._filters = { + "items": None, + "queryTerms": None, + } + for param, default in self._filters.items(): + setattr(self, param, kwargs.get(param, default)) diff --git a/tests/conftest.py b/tests/conftest.py index b16baaa..1850d8b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,6 +6,7 @@ import pytest +from here_location_services.autosuggest_api import AutosuggestApi from here_location_services.exceptions import ConfigException from here_location_services.geocoding_search_api import GeocodingSearchApi from here_location_services.isoline_routing_api import IsolineRoutingApi @@ -43,6 +44,13 @@ def routing_api(): return api +@pytest.fixture() +def autosuggest_api(): + """Create shared low level Location services AutosuggestApi instance as a pytest fixture.""" + api = AutosuggestApi(api_key=LS_API_KEY) + return api + + def env_setup_done(): """This function will return env variables required to authenticate APIs using auth token.""" try: diff --git a/tests/test_ls.py b/tests/test_ls.py index 547c192..2f24521 100644 --- a/tests/test_ls.py +++ b/tests/test_ls.py @@ -10,6 +10,7 @@ from geojson import FeatureCollection from here_location_services import LS +from here_location_services.config.autosuggest_config import SearchBox, SearchCircle from here_location_services.config.base_config import ( ROUTING_MODE, SHIPPED_HAZARDOUS_GOODS, @@ -51,6 +52,32 @@ LS_API_KEY = get_apikey() +@pytest.mark.skipif(not LS_API_KEY, reason="No api key found.") +def test_ls_autosuggest(): + """Test autosuggest api.""" + ls = LS(api_key=LS_API_KEY) + resp = ls.autosuggest(q="res", limit=5, at=["52.93175,12.77165"]) + print(resp) + assert resp.items + search_in_circle1 = SearchCircle(lat=52.53, lng="13.38", radius="10000") + search_in_box1 = SearchBox( + westLng="13.08836", southLat="52.3381", eastLng="13.761", northLat="52.6755" + ) + + with pytest.raises(ValueError): + ls.autosuggest( + q="res", + ) + + with pytest.raises(ValueError): + ls.autosuggest( + q="res", + at=["-13.163068,-72.545128"], + search_in_box=search_in_box1, + search_in_circle=search_in_circle1, + ) + + @pytest.mark.skipif(not LS_API_KEY, reason="No api key found.") def test_ls_geocoding(): """Test geocoding api.""" diff --git a/tests/test_ls_apis.py b/tests/test_ls_apis.py index 6dbc22c..24b784d 100644 --- a/tests/test_ls_apis.py +++ b/tests/test_ls_apis.py @@ -18,6 +18,14 @@ LS_API_KEY = get_apikey() +@pytest.mark.skipif(not LS_API_KEY, reason="No api key found.") +def test_autosuggest(autosuggest_api): + """Test isonline routing api.""" + result = autosuggest_api.get_autosuggest(q="res", limit=5, at=["52.93175,12.77165"]) + + assert result + + @pytest.mark.skipif(not LS_API_KEY, reason="No api key found.") def test_geocoding(geo_search_api): """Test geocoding api.""" From 3f44663af738667c85cd298a5de5b33a7ac21a46 Mon Sep 17 00:00:00 2001 From: Aayush Jain Date: Wed, 18 Aug 2021 18:50:07 +0530 Subject: [PATCH 2/5] fixes --- here_location_services/autosuggest_api.py | 49 ++++++++++++++----- .../config/autosuggest_config.py | 32 ++++++++++-- here_location_services/ls.py | 44 ++++++++++++++--- here_location_services/responses.py | 2 +- tests/test_ls.py | 33 ++++++++++++- tests/test_ls_apis.py | 8 +-- 6 files changed, 139 insertions(+), 29 deletions(-) diff --git a/here_location_services/autosuggest_api.py b/here_location_services/autosuggest_api.py index b36f8bb..4ab5edc 100644 --- a/here_location_services/autosuggest_api.py +++ b/here_location_services/autosuggest_api.py @@ -37,15 +37,36 @@ def get_autosuggest( terms_limit: Optional[int] = None, lang: Optional[List] = None, political_view: Optional[str] = None, - show: Optional[str] = None, + show: Optional[List] = None, ): - """Calculate route between two endpoints. + """Suggest address or place candidates based on an incomplete or misspelled query - See further information `here _`. + :param q: A string for free-text query. Example: res, rest + :param at: Specify the center of the search context expressed as coordinates + One of `at`, `search_in_circle` or `search_in_box` is required. + Parameters "at", "search_in_circle" and "search_in_box" are mutually exclusive. Only + one of them is allowed. + :param search_in_circle: Search within a circular geographic area provided as + latitude, longitude, and radius (in meters) + :param search_in_box: Search within a rectangular bounding box geographic area provided + as west longitude, south latitude, east longitude, north latitude + :param in_country: Search within a specific or multiple countries provided as + comma-separated ISO 3166-1 alpha-3 country codes. The country codes are to be + provided in all uppercase. Must be accompanied by exactly one of + `at`, `search_in_circle` or `search_in_box`. + :param limit: An integer specifiying maximum number of results to be returned. + :param terms_limit: An integer specifiying maximum number of Query Terms Suggestions + to be returned. + :param lang: Array of string to select the language to be used for result rendering + from a list of BCP 47 compliant language codes. + :param political_view: Toggle the political view. + :param show: Select additional fields to be rendered in the response. Please note + that some of the fields involve additional webservice calls and can increase + the overall response time. + :return: :class:`requests.Response` object. + :raises ApiError: If ``status_code`` of API response is not 200. - :param transport_mode: A string to represent mode of transport. - - """ # noqa E501 + """ path = "v1/autosuggest" url = f"{self._base_url}/{path}" params: Dict[str, str] = { @@ -54,10 +75,16 @@ def get_autosuggest( if at: params["at"] = ",".join([str(i) for i in at]) if in_country: - params["in[countryCode]"] = ",".join([str(i) for i in in_country]) + params["in"] = "countryCode:" + ",".join([str(i) for i in in_country]) if search_in_circle: - params["in[circle]"] = search_in_circle.lat + "," + search_in_circle.lng - params["in[r]"] = str(search_in_circle.radius) + params["in"] = ( + "circle:" + + str(search_in_circle.lat) + + "," + + str(search_in_circle.lng) + + ";r=" + + str(search_in_circle.radius) + ) if limit: params["limit"] = str(limit) if terms_limit: @@ -67,9 +94,9 @@ def get_autosuggest( if political_view: params["politicalView"] = political_view if show: - params["show"] = show + params["show"] = ",".join([str(i) for i in show]) if search_in_box: - params["in[bbox]"] = ( + params["in"] = "bbox:" + ( search_in_box.west + "," + search_in_box.south diff --git a/here_location_services/config/autosuggest_config.py b/here_location_services/config/autosuggest_config.py index d381850..a99b2ab 100644 --- a/here_location_services/config/autosuggest_config.py +++ b/here_location_services/config/autosuggest_config.py @@ -9,7 +9,8 @@ class SearchCircle: """A class to define ``SearchCircle`` - Results will be returned if they are located within the specified circular area defined by its center and radius(in meters). + Results will be returned if they are located within the specified circular area + defined by its center and radius(in meters). """ def __init__(self, lat: str, lng: str, radius: int): @@ -21,7 +22,8 @@ def __init__(self, lat: str, lng: str, radius: int): class SearchBox: """A class to define ``SearchBox`` - Results will be returned if they are located within the specified rectangular area defined by its west longitude, south latitude, east longitude, north latitude + Results will be returned if they are located within the specified rectangular + area defined by its west longitude, south latitude, east longitude, north latitude """ def __init__(self, westLng: str, southLat: str, eastLng: str, northLat: str): @@ -47,4 +49,28 @@ class PoliticalView(Bunch): #: Use this config for political_view of Autosuggest API. #: Example: for ``RUS`` political_view use ``POLITICAL_VIEW.RUS``. -POLITICAL_VIEW = PoliticalView(**{"RUS": "RUS", "SRB": "SRB", "MAR": "MAR", }) +POLITICAL_VIEW = PoliticalView( + **{ + "RUS": "RUS", + "SRB": "SRB", + "MAR": "MAR", + } +) + + +class Show(Bunch): + """A Class to define constant values for showing additional fields to be + rendered in the response + + ``phonemes``: + Renders phonemes for address and place names into the results. + + ``tz``: + BETA: Renders result items with additional time zone information. + Please note that this may impact latency significantly. + """ + + +#: Use this config for show of Autosuggest API. +#: Example: for ``RUS`` show use ``SHOW.phonemes``. +SHOW = Show(**{"phonemes": "phonemes", "tz": "tz"}) diff --git a/here_location_services/ls.py b/here_location_services/ls.py index 5b9bd1d..cc1c3f6 100644 --- a/here_location_services/ls.py +++ b/here_location_services/ls.py @@ -253,21 +253,49 @@ def autosuggest( terms_limit: Optional[int] = None, lang: Optional[List] = None, political_view: Optional[str] = None, - show: Optional[str] = None, + show: Optional[List] = None, ) -> AutosuggestResponse: - """Calculate isoline routing. - - Request a polyline that connects the endpoints of all routes - leaving from one defined center with either a specified length - or specified travel time. - - + """Suggest address or place candidates based on an incomplete or misspelled query + + :param q: A string for free-text query. Example: res, rest + :param at: Specify the center of the search context expressed as coordinates + One of `at`, `search_in_circle` or `search_in_box` is required. + Parameters "at", "search_in_circle" and "search_in_box" are mutually exclusive. Only + one of them is allowed. + :param search_in_circle: Search within a circular geographic area provided as + latitude, longitude, and radius (in meters) + :param search_in_box: Search within a rectangular bounding box geographic area provided + as west longitude, south latitude, east longitude, north latitude + :param in_country: Search within a specific or multiple countries provided as + comma-separated ISO 3166-1 alpha-3 country codes. The country codes are to be + provided in all uppercase. Must be accompanied by exactly one of + `at`, `search_in_circle` or `search_in_box`. + :param limit: An integer specifiying maximum number of results to be returned. + :param terms_limit: An integer specifiying maximum number of Query Terms Suggestions + to be returned. + :param lang: Array of string to select the language to be used for result rendering + from a list of BCP 47 compliant language codes. + :param political_view: Toggle the political view. + :param show: Select additional fields to be rendered in the response. Please note + that some of the fields involve additional webservice calls and can increase + the overall response time. + :return: :class:`requests.Response` object. + :raises ValueError: If ``search_in_circle``,``search_in_box`` and ``destination`` + are provided togrther. """ if search_in_circle and search_in_box and at: raise ValueError( "`search_in_circle` and `search_in_box` and `at` can not be provided together." ) + if search_in_circle and search_in_box: + raise ValueError( + "`search_in_circle` and `search_in_box` can not be provided together." + ) + if search_in_box and at: + raise ValueError("`search_in_box` and `at` can not be provided together.") + if search_in_circle and at: + raise ValueError("`search_in_circle` and `at` can not be provided together.") if search_in_circle is None and search_in_box is None and at is None: raise ValueError( "please provide either `search_in_circle` or `search_in_box` or `at`." diff --git a/here_location_services/responses.py b/here_location_services/responses.py index ad07174..161af4c 100644 --- a/here_location_services/responses.py +++ b/here_location_services/responses.py @@ -183,7 +183,7 @@ def to_travel_times_matrix(self): class AutosuggestResponse(ApiResponse): - """A class representing the Reverse Isoline routing API response data.""" + """A class representing the Autosuggest API response data.""" def __init__(self, **kwargs): super().__init__() diff --git a/tests/test_ls.py b/tests/test_ls.py index 2f24521..4c194f2 100644 --- a/tests/test_ls.py +++ b/tests/test_ls.py @@ -10,7 +10,12 @@ from geojson import FeatureCollection from here_location_services import LS -from here_location_services.config.autosuggest_config import SearchBox, SearchCircle +from here_location_services.config.autosuggest_config import ( + POLITICAL_VIEW, + SHOW, + SearchBox, + SearchCircle, +) from here_location_services.config.base_config import ( ROUTING_MODE, SHIPPED_HAZARDOUS_GOODS, @@ -57,13 +62,30 @@ def test_ls_autosuggest(): """Test autosuggest api.""" ls = LS(api_key=LS_API_KEY) resp = ls.autosuggest(q="res", limit=5, at=["52.93175,12.77165"]) - print(resp) assert resp.items + search_in_circle1 = SearchCircle(lat=52.53, lng="13.38", radius="10000") search_in_box1 = SearchBox( westLng="13.08836", southLat="52.3381", eastLng="13.761", northLat="52.6755" ) + # resp2 = ls.autosuggest(q="res", limit=5, search_in_box=search_in_box1) + resp2 = ls.autosuggest(q="res", limit=5, at=["-13.163068,-72.545128"], in_country=["USA"]) + assert resp2.items + + resp3 = ls.autosuggest(q="res", limit=5, search_in_circle=search_in_circle1, lang=["en"]) + assert resp3.items + + resp4 = ls.autosuggest( + q="res", + limit=5, + search_in_box=search_in_box1, + terms_limit=3, + show=[SHOW.phonemes], + political_view=POLITICAL_VIEW.RUS, + ) + assert resp4.items + with pytest.raises(ValueError): ls.autosuggest( q="res", @@ -77,6 +99,13 @@ def test_ls_autosuggest(): search_in_circle=search_in_circle1, ) + with pytest.raises(ApiError): + ls2 = LS(api_key="dummy") + ls2.autosuggest( + q="res", + at=["-13.163068,-72.545128"], + ) + @pytest.mark.skipif(not LS_API_KEY, reason="No api key found.") def test_ls_geocoding(): diff --git a/tests/test_ls_apis.py b/tests/test_ls_apis.py index 24b784d..88c01bb 100644 --- a/tests/test_ls_apis.py +++ b/tests/test_ls_apis.py @@ -20,10 +20,10 @@ @pytest.mark.skipif(not LS_API_KEY, reason="No api key found.") def test_autosuggest(autosuggest_api): - """Test isonline routing api.""" - result = autosuggest_api.get_autosuggest(q="res", limit=5, at=["52.93175,12.77165"]) - - assert result + """Test autosuggest api.""" + resp = autosuggest_api.get_autosuggest(q="res", limit=5, at=["52.93175,12.77165"]) + assert type(resp) == requests.Response + assert resp.status_code == 200 @pytest.mark.skipif(not LS_API_KEY, reason="No api key found.") From 726d0c210e7c073f9c1eabced2f3fb4f45702237 Mon Sep 17 00:00:00 2001 From: Aayush Jain Date: Thu, 19 Aug 2021 02:00:02 +0530 Subject: [PATCH 3/5] resolve issues --- here_location_services/autosuggest_api.py | 44 ++++++-------- .../config/autosuggest_config.py | 14 ----- here_location_services/ls.py | 57 ++++++++----------- tests/test_ls.py | 30 ++++------ tests/test_ls_apis.py | 2 +- 5 files changed, 53 insertions(+), 94 deletions(-) diff --git a/here_location_services/autosuggest_api.py b/here_location_services/autosuggest_api.py index 4ab5edc..8051ef3 100644 --- a/here_location_services/autosuggest_api.py +++ b/here_location_services/autosuggest_api.py @@ -4,9 +4,9 @@ """This module contains classes for accessing `HERE Autosuggest API `_. """ # noqa E501 -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Tuple -from here_location_services.config.autosuggest_config import SearchBox, SearchCircle +from here_location_services.config.autosuggest_config import SearchCircle from here_location_services.platform.auth import Auth from .apis import Api @@ -28,36 +28,36 @@ def __init__( def get_autosuggest( self, - q: str, + query: str, at: Optional[List] = None, search_in_circle: Optional[SearchCircle] = None, - search_in_box: Optional[SearchBox] = None, - in_country: Optional[List] = None, - limit: Optional[int] = None, + search_in_bbox: Optional[Tuple] = None, + in_country: Optional[List[str]] = None, + limit: Optional[int] = 20, terms_limit: Optional[int] = None, - lang: Optional[List] = None, + lang: Optional[List[str]] = None, political_view: Optional[str] = None, - show: Optional[List] = None, + show: Optional[List[str]] = None, ): """Suggest address or place candidates based on an incomplete or misspelled query - :param q: A string for free-text query. Example: res, rest + :param query: A string for free-text query. Example: res, rest :param at: Specify the center of the search context expressed as coordinates - One of `at`, `search_in_circle` or `search_in_box` is required. - Parameters "at", "search_in_circle" and "search_in_box" are mutually exclusive. Only + One of `at`, `search_in_circle` or `search_in_bbox` is required. + Parameters "at", "search_in_circle" and "search_in_bbox" are mutually exclusive. Only one of them is allowed. :param search_in_circle: Search within a circular geographic area provided as latitude, longitude, and radius (in meters) - :param search_in_box: Search within a rectangular bounding box geographic area provided - as west longitude, south latitude, east longitude, north latitude + :param search_in_bbox: Search within a rectangular bounding box geographic area provided + as tuple of west longitude, south latitude, east longitude, north latitude :param in_country: Search within a specific or multiple countries provided as comma-separated ISO 3166-1 alpha-3 country codes. The country codes are to be provided in all uppercase. Must be accompanied by exactly one of - `at`, `search_in_circle` or `search_in_box`. + `at`, `search_in_circle` or `search_in_bbox`. :param limit: An integer specifiying maximum number of results to be returned. :param terms_limit: An integer specifiying maximum number of Query Terms Suggestions to be returned. - :param lang: Array of string to select the language to be used for result rendering + :param lang: List of strings to select the language to be used for result rendering from a list of BCP 47 compliant language codes. :param political_view: Toggle the political view. :param show: Select additional fields to be rendered in the response. Please note @@ -70,7 +70,7 @@ def get_autosuggest( path = "v1/autosuggest" url = f"{self._base_url}/{path}" params: Dict[str, str] = { - "q": q, + "q": query, } if at: params["at"] = ",".join([str(i) for i in at]) @@ -95,16 +95,8 @@ def get_autosuggest( params["politicalView"] = political_view if show: params["show"] = ",".join([str(i) for i in show]) - if search_in_box: - params["in"] = "bbox:" + ( - search_in_box.west - + "," - + search_in_box.south - + "," - + search_in_box.east - + "," - + search_in_box.north - ) + if search_in_bbox: + params["in"] = "bbox:" + ",".join([str(i) for i in search_in_bbox]) resp = self.get(url, params=params, proxies=self.proxies) if resp.status_code == 200: return resp diff --git a/here_location_services/config/autosuggest_config.py b/here_location_services/config/autosuggest_config.py index a99b2ab..a97b5f7 100644 --- a/here_location_services/config/autosuggest_config.py +++ b/here_location_services/config/autosuggest_config.py @@ -19,20 +19,6 @@ def __init__(self, lat: str, lng: str, radius: int): self.radius = radius -class SearchBox: - """A class to define ``SearchBox`` - - Results will be returned if they are located within the specified rectangular - area defined by its west longitude, south latitude, east longitude, north latitude - """ - - def __init__(self, westLng: str, southLat: str, eastLng: str, northLat: str): - self.west = westLng - self.south = southLat - self.east = eastLng - self.north = northLat - - class PoliticalView(Bunch): """A Class to define constant values for political view diff --git a/here_location_services/ls.py b/here_location_services/ls.py index cc1c3f6..b9a1102 100644 --- a/here_location_services/ls.py +++ b/here_location_services/ls.py @@ -8,7 +8,7 @@ import urllib.request from datetime import datetime from time import sleep -from typing import Dict, List, Optional, Union +from typing import Dict, List, Optional, Tuple, Union from here_location_services.config.routing_config import Scooter, Via from here_location_services.platform.apis.aaa_oauth2_api import AAAOauth2Api @@ -16,7 +16,7 @@ from here_location_services.platform.credentials import PlatformCredentials from .autosuggest_api import AutosuggestApi -from .config.autosuggest_config import SearchBox, SearchCircle +from .config.autosuggest_config import SearchCircle from .config.base_config import PlaceOptions, Truck, WayPointOptions from .config.matrix_routing_config import ( AutoCircleRegion, @@ -205,7 +205,7 @@ def calculate_isoline( for ``destination``. :param destination_waypoint_options: :class:`WayPointOptions` optional waypoint options for ``destination``. - :raises ValueError: If ``start`` and ``destination`` are provided togrther. + :raises ValueError: If ``origin`` and ``destination`` are provided together. :return: :class:`IsolineResponse` object. """ @@ -244,67 +244,56 @@ def calculate_isoline( def autosuggest( self, - q: str, + query: str, at: Optional[List] = None, search_in_circle: Optional[SearchCircle] = None, - search_in_box: Optional[SearchBox] = None, - in_country: Optional[List] = None, - limit: Optional[int] = None, + search_in_bbox: Optional[Tuple] = None, + in_country: Optional[List[str]] = None, + limit: Optional[int] = 20, terms_limit: Optional[int] = None, - lang: Optional[List] = None, + lang: Optional[List[str]] = None, political_view: Optional[str] = None, - show: Optional[List] = None, + show: Optional[List[str]] = None, ) -> AutosuggestResponse: """Suggest address or place candidates based on an incomplete or misspelled query - :param q: A string for free-text query. Example: res, rest + :param query: A string for free-text query. Example: res, rest :param at: Specify the center of the search context expressed as coordinates - One of `at`, `search_in_circle` or `search_in_box` is required. - Parameters "at", "search_in_circle" and "search_in_box" are mutually exclusive. Only + One of `at`, `search_in_circle` or `search_in_bbox` is required. + Parameters "at", "search_in_circle" and "search_in_bbox" are mutually exclusive. Only one of them is allowed. :param search_in_circle: Search within a circular geographic area provided as latitude, longitude, and radius (in meters) - :param search_in_box: Search within a rectangular bounding box geographic area provided - as west longitude, south latitude, east longitude, north latitude + :param search_in_bbox: Search within a rectangular bounding box geographic area provided + as tuple of west longitude, south latitude, east longitude, north latitude :param in_country: Search within a specific or multiple countries provided as comma-separated ISO 3166-1 alpha-3 country codes. The country codes are to be provided in all uppercase. Must be accompanied by exactly one of - `at`, `search_in_circle` or `search_in_box`. + `at`, `search_in_circle` or `search_in_bbox`. :param limit: An integer specifiying maximum number of results to be returned. :param terms_limit: An integer specifiying maximum number of Query Terms Suggestions to be returned. - :param lang: Array of string to select the language to be used for result rendering + :param lang: List of strings to select the language to be used for result rendering from a list of BCP 47 compliant language codes. :param political_view: Toggle the political view. :param show: Select additional fields to be rendered in the response. Please note that some of the fields involve additional webservice calls and can increase the overall response time. :return: :class:`requests.Response` object. - :raises ValueError: If ``search_in_circle``,``search_in_box`` and ``destination`` - are provided togrther. + :raises ValueError: If ``search_in_circle``,``search_in_bbox`` and ``destination`` + are provided together. """ - if search_in_circle and search_in_box and at: - raise ValueError( - "`search_in_circle` and `search_in_box` and `at` can not be provided together." - ) - if search_in_circle and search_in_box: + i = iter([search_in_circle, search_in_bbox, at]) + if not (any(i) and not any(i)): raise ValueError( - "`search_in_circle` and `search_in_box` can not be provided together." - ) - if search_in_box and at: - raise ValueError("`search_in_box` and `at` can not be provided together.") - if search_in_circle and at: - raise ValueError("`search_in_circle` and `at` can not be provided together.") - if search_in_circle is None and search_in_box is None and at is None: - raise ValueError( - "please provide either `search_in_circle` or `search_in_box` or `at`." + "Exactly one of `search_in_circle` or `search_in_bbox` or `at` must be provided." ) resp = self.autosuggest_api.get_autosuggest( - q=q, + query=query, at=at, - search_in_box=search_in_box, + search_in_bbox=search_in_bbox, search_in_circle=search_in_circle, in_country=in_country, limit=limit, diff --git a/tests/test_ls.py b/tests/test_ls.py index 4c194f2..db49c0e 100644 --- a/tests/test_ls.py +++ b/tests/test_ls.py @@ -10,12 +10,7 @@ from geojson import FeatureCollection from here_location_services import LS -from here_location_services.config.autosuggest_config import ( - POLITICAL_VIEW, - SHOW, - SearchBox, - SearchCircle, -) +from here_location_services.config.autosuggest_config import POLITICAL_VIEW, SHOW, SearchCircle from here_location_services.config.base_config import ( ROUTING_MODE, SHIPPED_HAZARDOUS_GOODS, @@ -61,25 +56,22 @@ def test_ls_autosuggest(): """Test autosuggest api.""" ls = LS(api_key=LS_API_KEY) - resp = ls.autosuggest(q="res", limit=5, at=["52.93175,12.77165"]) + resp = ls.autosuggest(query="res", limit=5, at=["52.93175,12.77165"]) assert resp.items search_in_circle1 = SearchCircle(lat=52.53, lng="13.38", radius="10000") - search_in_box1 = SearchBox( - westLng="13.08836", southLat="52.3381", eastLng="13.761", northLat="52.6755" - ) + search_in_bbox1 = ("13.08836", "52.33812", "13.761", "52.6755") - # resp2 = ls.autosuggest(q="res", limit=5, search_in_box=search_in_box1) - resp2 = ls.autosuggest(q="res", limit=5, at=["-13.163068,-72.545128"], in_country=["USA"]) + resp2 = ls.autosuggest(query="res", limit=5, at=["-13.163068,-72.545128"], in_country=["USA"]) assert resp2.items - resp3 = ls.autosuggest(q="res", limit=5, search_in_circle=search_in_circle1, lang=["en"]) + resp3 = ls.autosuggest(query="res", limit=5, search_in_circle=search_in_circle1, lang=["en"]) assert resp3.items resp4 = ls.autosuggest( - q="res", + query="res", limit=5, - search_in_box=search_in_box1, + search_in_bbox=search_in_bbox1, terms_limit=3, show=[SHOW.phonemes], political_view=POLITICAL_VIEW.RUS, @@ -88,21 +80,21 @@ def test_ls_autosuggest(): with pytest.raises(ValueError): ls.autosuggest( - q="res", + query="res", ) with pytest.raises(ValueError): ls.autosuggest( - q="res", + query="res", at=["-13.163068,-72.545128"], - search_in_box=search_in_box1, + search_in_bbox=search_in_bbox1, search_in_circle=search_in_circle1, ) with pytest.raises(ApiError): ls2 = LS(api_key="dummy") ls2.autosuggest( - q="res", + query="res", at=["-13.163068,-72.545128"], ) diff --git a/tests/test_ls_apis.py b/tests/test_ls_apis.py index 88c01bb..d91b733 100644 --- a/tests/test_ls_apis.py +++ b/tests/test_ls_apis.py @@ -21,7 +21,7 @@ @pytest.mark.skipif(not LS_API_KEY, reason="No api key found.") def test_autosuggest(autosuggest_api): """Test autosuggest api.""" - resp = autosuggest_api.get_autosuggest(q="res", limit=5, at=["52.93175,12.77165"]) + resp = autosuggest_api.get_autosuggest(query="res", limit=5, at=["52.93175,12.77165"]) assert type(resp) == requests.Response assert resp.status_code == 200 From 0d307b359348debb3daf6b9493a290d2f01e8858 Mon Sep 17 00:00:00 2001 From: Aayush Jain Date: Thu, 19 Aug 2021 23:19:14 +0530 Subject: [PATCH 4/5] fix test --- here_location_services/autosuggest_api.py | 2 +- here_location_services/ls.py | 2 +- tests/test_ls.py | 23 ++++++++++++++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/here_location_services/autosuggest_api.py b/here_location_services/autosuggest_api.py index 8051ef3..170fb5e 100644 --- a/here_location_services/autosuggest_api.py +++ b/here_location_services/autosuggest_api.py @@ -42,7 +42,7 @@ def get_autosuggest( """Suggest address or place candidates based on an incomplete or misspelled query :param query: A string for free-text query. Example: res, rest - :param at: Specify the center of the search context expressed as coordinates + :param at: Specify the center of the search context expressed as list of coordinates One of `at`, `search_in_circle` or `search_in_bbox` is required. Parameters "at", "search_in_circle" and "search_in_bbox" are mutually exclusive. Only one of them is allowed. diff --git a/here_location_services/ls.py b/here_location_services/ls.py index b9a1102..224421d 100644 --- a/here_location_services/ls.py +++ b/here_location_services/ls.py @@ -258,7 +258,7 @@ def autosuggest( """Suggest address or place candidates based on an incomplete or misspelled query :param query: A string for free-text query. Example: res, rest - :param at: Specify the center of the search context expressed as coordinates + :param at: Specify the center of the search context expressed as list of coordinates One of `at`, `search_in_circle` or `search_in_bbox` is required. Parameters "at", "search_in_circle" and "search_in_bbox" are mutually exclusive. Only one of them is allowed. diff --git a/tests/test_ls.py b/tests/test_ls.py index db49c0e..8cafed3 100644 --- a/tests/test_ls.py +++ b/tests/test_ls.py @@ -56,17 +56,16 @@ def test_ls_autosuggest(): """Test autosuggest api.""" ls = LS(api_key=LS_API_KEY) - resp = ls.autosuggest(query="res", limit=5, at=["52.93175,12.77165"]) + resp = ls.autosuggest(query="bar", limit=5, at=["-13.163068,-72.545128"], in_country=["USA"]) assert resp.items + assert len(resp.items) <= 5 search_in_circle1 = SearchCircle(lat=52.53, lng="13.38", radius="10000") search_in_bbox1 = ("13.08836", "52.33812", "13.761", "52.6755") - resp2 = ls.autosuggest(query="res", limit=5, at=["-13.163068,-72.545128"], in_country=["USA"]) - assert resp2.items - - resp3 = ls.autosuggest(query="res", limit=5, search_in_circle=search_in_circle1, lang=["en"]) + resp3 = ls.autosuggest(query="bar", limit=5, search_in_circle=search_in_circle1, lang=["en"]) assert resp3.items + assert len(resp3.items) <= 5 resp4 = ls.autosuggest( query="res", @@ -77,12 +76,26 @@ def test_ls_autosuggest(): political_view=POLITICAL_VIEW.RUS, ) assert resp4.items + assert len(resp4.items) <= 5 + assert len(resp4.queryTerms) == 3 + + for item in resp4.items: + if item["resultType"] == "place": + assert item["politicalView"] + assert item["phonemes"] with pytest.raises(ValueError): ls.autosuggest( query="res", ) + with pytest.raises(ValueError): + ls.autosuggest( + query="res", + search_in_bbox=search_in_bbox1, + search_in_circle=search_in_circle1, + ) + with pytest.raises(ValueError): ls.autosuggest( query="res", From 79ddcd96cee128e223d621da7bbea9b2fe74ac5d Mon Sep 17 00:00:00 2001 From: Aayush Jain Date: Fri, 20 Aug 2021 00:05:05 +0530 Subject: [PATCH 5/5] add docs --- docs/notebooks/autosuggest.ipynb | 142 ++++++++++++++++++ docs/source/autosuggest.rst | 69 +++++++++ ...here_location_services.autosuggest_api.rst | 8 + ...ion_services.config.autosuggest_config.rst | 8 + docs/source/index.rst | 1 + 5 files changed, 228 insertions(+) create mode 100644 docs/notebooks/autosuggest.ipynb create mode 100644 docs/source/autosuggest.rst create mode 100644 docs/source/here_location_services.autosuggest_api.rst create mode 100644 docs/source/here_location_services.config.autosuggest_config.rst diff --git a/docs/notebooks/autosuggest.ipynb b/docs/notebooks/autosuggest.ipynb new file mode 100644 index 0000000..f7f1ade --- /dev/null +++ b/docs/notebooks/autosuggest.ipynb @@ -0,0 +1,142 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "source": [ + "import os\n", + "os.environ[\"LS_API_KEY\"] = \"MY-API-KEY\" # replace your API key here." + ], + "outputs": [], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 14, + "source": [ + "import os\n", + "\n", + "from here_location_services import LS\n", + "\n", + "LS_API_KEY = os.environ.get(\"LS_API_KEY\") # Get API KEY from environment.\n", + "ls = LS(api_key=LS_API_KEY)\n", + "\n", + "autosuggest_response = ls.autosuggest(\n", + " query=\"bar\",\n", + " limit=5,\n", + " at=[\"-13.163068,-72.545128\"],\n", + " terms_limit=3,\n", + ")\n", + "\n", + "print(\"Query Items:\")\n", + "for item in autosuggest_response.queryTerms:\n", + " print(item)\n", + "\n", + "print(\"Search Items:\")\n", + "for item in autosuggest_response.items:\n", + " print(item)" + ], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Query Items:\n", + "{'term': 'Barceló', 'replaces': 'bar', 'start': 0, 'end': 3}\n", + "{'term': 'Bardot', 'replaces': 'bar', 'start': 0, 'end': 3}\n", + "{'term': 'Barista', 'replaces': 'bar', 'start': 0, 'end': 3}\n", + "Search Items:\n", + "{'title': 'bar', 'id': 'here:cm:ontology:bar_pub', 'resultType': 'categoryQuery', 'href': 'https://autosuggest.search.hereapi.com/v1/discover?q=bar&_ontology=bar_pub&at=-13.16307%2C-72.54513', 'highlights': {'title': [{'start': 0, 'end': 3}]}}\n", + "{'title': 'El Mirador - Snack Bar', 'id': 'here:pds:place:6046msmj-b110bba85a894aca85bda8a5f8639bd9', 'resultType': 'place', 'address': {'label': 'El Mirador - Snack Bar, Carretera Hiram Bingham, 08680 Machu Picchu, Perú'}, 'position': {'lat': -13.16579, 'lng': -72.54314}, 'access': [{'lat': -13.16578, 'lng': -72.54315}], 'distance': 371, 'categories': [{'id': '100-1000-0001', 'name': 'Restaurante informal', 'primary': True}, {'id': '100-1000-0000', 'name': 'Restaurante'}], 'highlights': {'title': [{'start': 19, 'end': 22}], 'address': {'label': [{'start': 19, 'end': 22}]}}}\n", + "{'title': 'Bar Pisco Brothers', 'id': 'here:pds:place:6046msmj-f80954cdf3b644389d0072d758d63210', 'resultType': 'place', 'address': {'label': 'Bar Pisco Brothers, Avenida Wakanki, 08681 Machu Picchu, Perú'}, 'position': {'lat': -13.15607, 'lng': -72.52229}, 'access': [{'lat': -13.15614, 'lng': -72.52241}], 'distance': 2593, 'categories': [{'id': '200-2000-0011', 'name': 'Bar o pub', 'primary': True}], 'highlights': {'title': [{'start': 0, 'end': 3}], 'address': {'label': [{'start': 0, 'end': 3}]}}}\n", + "{'title': \"Bar & Snack Tortu's\", 'id': 'here:pds:place:6046msmj-1df092f0321242b992e8636c412962c0', 'resultType': 'place', 'address': {'label': \"Bar & Snack Tortu's, Calle Aymuraypa Tikan, 08681 Machu Picchu, Perú\"}, 'position': {'lat': -13.15571, 'lng': -72.52318}, 'access': [{'lat': -13.15585, 'lng': -72.52315}], 'distance': 2514, 'categories': [{'id': '200-2000-0011', 'name': 'Bar o pub', 'primary': True}], 'highlights': {'title': [{'start': 0, 'end': 3}], 'address': {'label': [{'start': 0, 'end': 3}]}}}\n", + "{'title': 'Barnim (BAR), Brandenburg, Deutschland', 'id': 'here:cm:namedplace:20187485', 'resultType': 'administrativeArea', 'administrativeAreaType': 'county', 'address': {'label': 'Barnim, Brandenburg, Deutschland'}, 'position': {'lat': 52.83392, 'lng': 13.81271}, 'distance': 10928834, 'mapView': {'west': 13.37457, 'south': 52.54565, 'east': 14.15673, 'north': 53.05861}, 'highlights': {'title': [], 'address': {'label': []}}}\n" + ] + } + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 18, + "source": [ + "from here_map_widget import Map, Marker, Group\n", + "\n", + "results = []\n", + "for item in autosuggest_response.items:\n", + " if item[\"resultType\"] == \"place\":\n", + " results.append(\n", + " Marker(\n", + " lat=item[\"position\"][\"lat\"],\n", + " lng=item[\"position\"][\"lng\"],\n", + " data=item[\"title\"],\n", + " )\n", + " )\n", + "group = Group(volatility=True)\n", + "group.add_objects(results)\n", + "m = Map(\n", + " api_key=LS_API_KEY,\n", + " center=[-13.163068,-72.545128],\n", + " zoom=14,\n", + ")\n", + "m.add_object(group)\n", + "m" + ], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Markers placed: 3\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Map(api_key='TKURWbpJHcbzmWMrmTZwGAdSTLrX8WY1oddj4S4U-EM', basemap=None, center=[-13.163068, -72.545128], obje…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "35877ce533064bf0a88e5cb48f5ded91" + } + }, + "metadata": {} + } + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "source": [], + "outputs": [], + "metadata": {} + } + ], + "metadata": { + "orig_nbformat": 4, + "language_info": { + "name": "python", + "version": "3.9.6", + "mimetype": "text/x-python", + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "pygments_lexer": "ipython3", + "nbconvert_exporter": "python", + "file_extension": ".py" + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3.9.6 64-bit" + }, + "interpreter": { + "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/docs/source/autosuggest.rst b/docs/source/autosuggest.rst new file mode 100644 index 0000000..23e2641 --- /dev/null +++ b/docs/source/autosuggest.rst @@ -0,0 +1,69 @@ +Autosuggest +=============== +`Autosuggest endpoint of HERE Geocoding & Search API `_ improves the user's search experience by allowing submittal of free-form, incomplete and misspelled addresses or place names to the endpoint. + +Example +------- + +.. jupyter-execute:: + + import os + + from here_location_services import LS + from here_map_widget import Map, Marker, Group + + LS_API_KEY = os.environ.get("LS_API_KEY") # Get API KEY from environment. + ls = LS(api_key=LS_API_KEY) + + autosuggest_response = ls.autosuggest( + query="bar", + limit=5, + at=["-13.163068,-72.545128"], + terms_limit=3, + ) + + print("Query Items:") + for item in autosuggest_response.queryTerms: + print(item) + + print("Search Items:") + for item in autosuggest_response.items: + print(item) + + results = [] + for item in autosuggest_response.items: + if item["resultType"] == "place": + results.append( + Marker( + lat=item["position"]["lat"], + lng=item["position"]["lng"], + data=item["title"], + ) + ) + group = Group(volatility=True) + group.add_objects(results) + m = Map( + api_key=LS_API_KEY, + center=[-13.163068,-72.545128], + zoom=14, + ) + m.add_object(group) + m + +Attributes +---------- + +==================== ======================================================================================= === +Attribute Type Doc +==================== ======================================================================================= === +query string A string for free-text query. Example: `res`, `rest` +at list optional Specify the center of the search context expressed as list of coordinates. One of `at`, `search_in_circle` or `search_in_bbox` is required. Parameters "at", "search_in_circle" and "search_in_bbox" are mutually exclusive. Only one of them is allowed. +search_in_circle :class:`SearchCircle ` optional Search within a circular geographic area provided as latitude, longitude, and radius (in meters) +search_in_bbox tuple optional Search within a rectangular bounding box geographic area provided as tuple of west longitude, south latitude, east longitude, north latitude +in_country list optional Search within a specific or multiple countries provided as comma-separated ISO 3166-1 alpha-3 country codes. The country codes are to be provided in all uppercase. Must be accompanied by exactly one of `at`, `search_in_circle` or `search_in_bbox`. +limit int optional An integer specifiying maximum number of results to be returned. +terms_limit int optional An integer specifiying maximum number of Query Terms Suggestions to be returned. +lang list optional List of strings to select the language to be used for result rendering from a list of BCP 47 compliant language codes. +political_view string optional Toggle the political view by passing a string from :attr:`POLITICAL_VIEW `. +show list optional Select additional fields from :attr:`SHOW `. to be rendered in the response. +==================== ======================================================================================= === \ No newline at end of file diff --git a/docs/source/here_location_services.autosuggest_api.rst b/docs/source/here_location_services.autosuggest_api.rst new file mode 100644 index 0000000..96851eb --- /dev/null +++ b/docs/source/here_location_services.autosuggest_api.rst @@ -0,0 +1,8 @@ +here\_location\_services.autosuggest\_api module +================================================ + +.. automodule:: here_location_services.autosuggest_api + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/here_location_services.config.autosuggest_config.rst b/docs/source/here_location_services.config.autosuggest_config.rst new file mode 100644 index 0000000..a45de00 --- /dev/null +++ b/docs/source/here_location_services.config.autosuggest_config.rst @@ -0,0 +1,8 @@ +here\_location\_services.config.autosuggest\_config module +========================================================== + +.. automodule:: here_location_services.config.autosuggest_config + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/index.rst b/docs/source/index.rst index 2d087f4..932e2c2 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -26,6 +26,7 @@ A Python client for `HERE Location Services`_. Discover Browse Lookup + Autosugggest .. toctree:: :maxdepth: 1