Skip to content

Commit

Permalink
Improve search and metadata methods - #73
Browse files Browse the repository at this point in the history
Search options, search perfs (async), search model and more.
  • Loading branch information
Guts committed Aug 19, 2019
2 parents 620d765 + 53237ef commit 667827f
Show file tree
Hide file tree
Showing 31 changed files with 1,064 additions and 322 deletions.
4 changes: 2 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ jobs:
ISOGEO_API_URL: $(ISOGEO_API_URL)
ISOGEO_ID_URL: $(ISOGEO_ID_URL)
# oAuth2 Client Credentials Grant
ISOGEO_API_DEV_ID: $(ISOGEO_API_DEV_ID)
ISOGEO_API_DEV_SECRET: $(ISOGEO_API_DEV_SECRET)
ISOGEO_API_GROUP_CLIENT_ID: $(ISOGEO_API_GROUP_CLIENT_ID)
ISOGEO_API_GROUP_CLIENT_SECRET: $(ISOGEO_API_GROUP_CLIENT_SECRET)
# oAuth2 Legacy Application Client
ISOGEO_API_USER_LEGACY_CLIENT_ID: $(ISOGEO_API_USER_LEGACY_CLIENT_ID)
ISOGEO_API_USER_LEGACY_CLIENT_SECRET: $(ISOGEO_API_USER_LEGACY_CLIENT_SECRET)
Expand Down
10 changes: 5 additions & 5 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Add shares tags to search response and as attributes
token = isogeo.connect()
# set augment option on True
search = isogeo.search(token, page_size=0, whole_share=0, augment=1)
search = isogeo.search(token, page_size=0, whole_results=0, augment=1)
# through search tags
print(search.get("tags"))
Expand Down Expand Up @@ -92,7 +92,7 @@ The share UUID is required: 2 methods are proposed to retrieve it.
# empty search
search = isogeo.search(token,
page_size=0, # get only tags, not results
whole_share=0, # do not retrieve the whole application scope
whole_results=0, # do not retrieve the whole application scope
augment=1 # -> this parameter is what we need
)
Expand Down Expand Up @@ -123,7 +123,7 @@ With the augmented share, it's also possible to check if a metadata is present w
# get a metadata
search = isogeo.search(token,
page_size=1, # get only one result
whole_share=0 # do not retrieve the whole application scope
whole_results=0 # do not retrieve the whole application scope
)
md = search.get("results")[0]
Expand Down Expand Up @@ -307,7 +307,7 @@ In Isogeo, every metadata resource can be downloaded in its XML version (ISO 191
search_to_be_exported = isogeo.search(token,
page_size=10,
query="type:dataset",
whole_share=0
whole_results=0
)
# loop on results and export
Expand Down Expand Up @@ -348,7 +348,7 @@ Administrators and editors can link raw data and docs (.zip, .pdf...) to metadat
latest_data_modified = isogeo.search(token,
page_size=10,
order_by="modified",
whole_share=0,
whole_results=0,
query="action:download",
include=["links"],
)
Expand Down
6 changes: 2 additions & 4 deletions isogeo_pysdk/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@
from .routes_invitation import ApiInvitation # noqa: F401
from .routes_license import ApiLicense # noqa: F401
from .routes_metadata import ApiMetadata # noqa: F401
from .routes_share import ApiShare # noqa: F401
from .routes_search import ApiSearch # noqa: F401
from .routes_service import ApiService # noqa: F401
from .routes_service_layers import ApiServiceLayer # noqa: F401
from .routes_service_operations import ApiServiceOperation # noqa: F401
from .routes_share import ApiShare # noqa: F401
from .routes_specification import ApiSpecification # noqa: F401
from .routes_thesaurus import ApiThesaurus # noqa: F401
from .routes_user import ApiUser # noqa: F401
from .routes_workgroup import ApiWorkgroup # noqa: F401

# shortcuts or confusion reducers
ApiMetadata = ApiMetadata
3 changes: 3 additions & 0 deletions isogeo_pysdk/api/routes_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

# Standard library
import logging
from functools import lru_cache

# submodules
from isogeo_pysdk.checker import IsogeoChecker
Expand Down Expand Up @@ -51,6 +52,7 @@ def __init__(self, api_client=None):
# initialize
super(ApiAccount, self).__init__()

@lru_cache()
@ApiDecorators._check_bearer_validity
def account(self, include: list = ["_abilities"], caching: bool = 1) -> User:
"""Get authenticated user account(= profile) informations.
Expand Down Expand Up @@ -125,6 +127,7 @@ def update(self, account: User, caching: bool = 1) -> User:
return User(**req_account_update.json())

# -- Routes to manage the related objects ------------------------------------------
@lru_cache()
@ApiDecorators._check_bearer_validity
def memberships(self) -> list:
"""Returns memberships for the authenticated user.
Expand Down
3 changes: 3 additions & 0 deletions isogeo_pysdk/api/routes_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

# Standard library
import logging
from functools import lru_cache

# submodules
from isogeo_pysdk.checker import IsogeoChecker
Expand Down Expand Up @@ -51,6 +52,7 @@ def __init__(self, api_client=None):
# initialize
super(ApiApplication, self).__init__()

@lru_cache()
@ApiDecorators._check_bearer_validity
def listing(
self,
Expand Down Expand Up @@ -329,6 +331,7 @@ def update(self, application: Application, caching: bool = 1) -> Application:
return new_application

# -- Routes to manage the related objects ------------------------------------------
@lru_cache()
@ApiDecorators._check_bearer_validity
def workgroups(self, application_id: str = None) -> list:
"""Get all groups associated with an application.
Expand Down
7 changes: 7 additions & 0 deletions isogeo_pysdk/api/routes_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

# Standard library
import logging
from functools import lru_cache

# 3rd party
from requests.exceptions import Timeout
Expand Down Expand Up @@ -56,6 +57,7 @@ def __init__(self, api_client=None):
# initialize
super(ApiCatalog, self).__init__()

@lru_cache()
@ApiDecorators._check_bearer_validity
def listing(
self,
Expand Down Expand Up @@ -109,6 +111,7 @@ def listing(
# end of method
return wg_catalogs

@lru_cache()
@ApiDecorators._check_bearer_validity
def metadata(self, metadata_id: str) -> list:
"""List metadata's catalogs with complete information.
Expand Down Expand Up @@ -148,6 +151,7 @@ def metadata(self, metadata_id: str) -> list:
# end of method
return req_metadata_catalogs.json()

@lru_cache()
@ApiDecorators._check_bearer_validity
def get(
self,
Expand Down Expand Up @@ -503,6 +507,7 @@ def dissociate_metadata(self, metadata: Metadata, catalog: Catalog) -> Response:
# end of method
return req_catalog_dissociation

@lru_cache()
@ApiDecorators._check_bearer_validity
def shares(self, catalog_id: str) -> list:
"""Returns shares for the specified catalog.
Expand Down Expand Up @@ -539,6 +544,7 @@ def shares(self, catalog_id: str) -> list:

return req_catalog_shares.json()

@lru_cache()
@ApiDecorators._check_bearer_validity
def statistics(self, catalog_id: str) -> dict:
"""Returns statistics for the specified catalog.
Expand Down Expand Up @@ -572,6 +578,7 @@ def statistics(self, catalog_id: str) -> dict:

return req_catalog_statistics.json()

@lru_cache()
@ApiDecorators._check_bearer_validity
def statistics_by_tag(self, catalog_id: str, tag: str) -> dict:
"""Returns statistics on a specific tag for the specified catalog.
Expand Down
2 changes: 1 addition & 1 deletion isogeo_pysdk/api/routes_coordinate_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ def associate_workgroup(
>>> coordsys.alias = "World SRS"
>>> # add it to the workgroup selection
>>> isogeo.srs.associate_workgroup(
workgroup=isogeo.workgroup.workgroup(WORKGROUP_UUID),
workgroup=isogeo.workgroup.get(WORKGROUP_UUID),
coordinate_system=coordsys
)
"""
Expand Down
172 changes: 1 addition & 171 deletions isogeo_pysdk/api/routes_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from isogeo_pysdk.exceptions import AlreadyExistError
from isogeo_pysdk.checker import IsogeoChecker
from isogeo_pysdk.decorators import ApiDecorators
from isogeo_pysdk.models import Metadata, ResourceSearch
from isogeo_pysdk.models import Metadata
from isogeo_pysdk.utils import IsogeoUtils

# other routes
Expand Down Expand Up @@ -316,176 +316,6 @@ def update(self, metadata: Metadata) -> Metadata:
# return updated object
return Metadata(**req_metadata_update.json())

# -- Routes to search --------------------------------------------------------------
@ApiDecorators._check_bearer_validity
def search(
self,
# semantic and objects filters
query: str = "",
share: str = None,
specific_md: list = [],
# results model
include: list = [],
# geographic filters
bbox: list = None,
poly: str = None,
georel: str = None,
# sorting
order_by: str = "_created",
order_dir: str = "desc",
# results size
page_size: int = 20,
offset: int = 0,
# specific options of implemention
# augment: bool = False,
check: bool = True,
# tags_as_dicts: bool = False,
# whole_share: bool = True,
) -> ResourceSearch:
"""Search within the resources shared to the application. It's the mainly used method to retrieve metadata.
:param str query: search terms and semantic filters. Equivalent of
**q** parameter in Isogeo API. It could be a simple
string like *oil* or a tag like *keyword:isogeo:formations*
or *keyword:inspire-theme:landcover*. The *AND* operator
is applied when various tags are passed.
:param list bbox: Bounding box to limit the search. Must be a 4 list of coordinates in WGS84 (EPSG 4326). Could be associated with *georel*.
:param str poly: Geographic criteria for the search, in WKT format. Could be associated with *georel*.
:param str georel: geometric operator to apply to the `bbox` or `poly` parameters. Available values:
* 'contains',
* 'disjoint',
* 'equals',
* 'intersects' - [APPLIED BY API if NOT SPECIFIED]
* 'overlaps',
* 'within'.
:param str order_by: sorting results. Available values:
* '_created': metadata creation date [DEFAULT if relevance is null]
* '_modified': metadata last update
* 'title': metadata title
* 'created': data creation date (possibly None)
* 'modified': data last update date
* 'relevance': relevance score calculated by API [DEFAULT].
:param str order_dir: sorting direction. Available values:
* 'desc': descending
* 'asc': ascending
:param int page_size: limits the number of results.
Useful to paginate results display. Default value: 100.
:param int offset: offset to start page size
from a specific results index
:param str share: share UUID to filter on
:param list specific_md: list of metadata UUIDs to filter on
:param list include: subresources that should be returned.
Must be a list of strings. Available values: *isogeo.SUBRESOURCES*
:param bool whole_share: option to return all results or only the
page size. *True* by DEFAULT.
:param bool check: option to check query parameters and avoid erros.
*True* by DEFAULT.
:param bool augment: option to improve API response by adding
some tags on the fly (like shares_id)
:param bool tags_as_dicts: option to store tags as key/values by filter.
"""
# handling request parameters
payload = {
"_id": checker._check_filter_specific_md(specific_md),
"_include": checker._check_filter_includes(
includes=include, entity="metadata"
),
"_limit": page_size,
"_offset": offset,
"box": bbox,
"geo": poly,
"rel": georel,
"ob": order_by,
"od": order_dir,
"q": query,
"s": share,
}

# check params
if check:
checker.check_request_parameters(payload)
else:
pass

# URL
url_resources_search = utils.get_request_base_url(route="resources/search")

# request
req_metadata_search = self.api_client.get(
url=url_resources_search,
headers=self.api_client.header,
params=payload,
proxies=self.api_client.proxies,
verify=self.api_client.ssl,
timeout=(5, 200),
)

# checking response
req_check = checker.check_api_response(req_metadata_search)
if isinstance(req_check, tuple):
return req_check

# end of method
return ResourceSearch(**req_metadata_search.json())

# def workgroup_metadata(
# self,
# workgroup_id: str,
# order_by: str = "_created",
# order_dir: str = "desc",
# page_size: int = 100,
# offset: int = 0,
# ) -> dict:
# """List workgroup metadata.

# :param str workgroup_id: identifier of the owner workgroup
# """
# # check workgroup UUID
# if not checker.check_is_uuid(workgroup_id):
# raise ValueError("Workgroup ID is not a correct UUID.")
# else:
# pass

# # request parameters
# payload = {
# # "_include": include,
# # "_lang": self.lang,
# "_limit": page_size,
# "_offset": offset,
# "ob": order_by,
# "od": order_dir,
# # "q": query,
# # "s": share,
# }

# # build request url
# url_metadata_list = utils.get_request_base_url(
# route="groups/{}/resources/search".format(workgroup_id)
# )

# wg_metadata = self.api_client.get(
# url_metadata_list,
# headers=self.api_client.header,
# params=payload,
# proxies=self.api_client.proxies,
# verify=self.api_client.ssl,
# timeout=self.api_client.timeout,
# )

# wg_metadata = wg_metadata.json()

# # # if caching use or store the workgroup metadata
# # if caching and not self._wg_apps_names:
# # self._wg_apps_names = {i.get("name"): i.get("_id") for i in wg_metadata}

# return wg_metadata

# -- Routes to manage the related objects ------------------------------------------
@ApiDecorators._check_bearer_validity
def download_xml(self, metadata: Metadata) -> Response:
Expand Down

0 comments on commit 667827f

Please sign in to comment.