diff --git a/src/repdav/tgapi.py b/src/repdav/tgapi.py index f5c2b6e610c83bb79f01b5d59d4fd2f6f9315553..c3ef2583d2e49677b04f7c292e2fbd965d38e530 100644 --- a/src/repdav/tgapi.py +++ b/src/repdav/tgapi.py @@ -1,17 +1,16 @@ -"""Communication with the different Textgrid APIs. -""" +"""Communicate with the different Textgrid APIs.""" import io -import logging -import requests import xml.etree.ElementTree as ET + +import requests #from typing import List from zeep import Client from zeep.exceptions import TransportError from .config import TextgridConfig +__docformat__ = 'restructuredtext en' DEFAULT_API_VERSION = "1.0" -_logger = logging.getLogger(__name__) def lookup_api_path(internal_name: str, api_version: str = DEFAULT_API_VERSION) -> str: @@ -52,7 +51,8 @@ class TextgridAuth: self._config = TextgridConfig() def _connect(self) -> Client: - """Internal helper that provides a SOAP client that is configured for the use with the Textgrid Auth service. + """Internal helper that provides a SOAP client that is configured for + the use with the Textgrid Auth service. :return: A SOAP client :rtype: zeep.Client @@ -89,9 +89,9 @@ class TextgridSearch: :rtype: dict """ uri = self._config.host + DEFAULT_API_VERSION + lookup_api_path("info") - r = requests.get(uri + textgrid_uri + "?sid=" + sid) + response = requests.get(uri + textgrid_uri + "?sid=" + sid) # TODO implement error handling on http status not in 200..299 - return self._process_response(r) + return self._process_response(response) def get_project_contents(self, sid: str, project_id: str) -> dict: """Get objects belonging to a project, filtered by objects that are in @@ -100,8 +100,9 @@ class TextgridSearch: :return: A dictionary with keys of Textgrid URIs and values of metadata dictionaries :rtype: dict """ - r = requests.get(self._config.nav_address + project_id + "?sid=" + sid) - return self._process_response(r) + response = requests.get( + self._config.nav_address + project_id + "?sid=" + sid) + return self._process_response(response) def get_aggregation_contents(self, sid: str, textgrid_uri: str) -> dict: """Get child resources of an aggregation. @@ -113,9 +114,9 @@ class TextgridSearch: :return: A dictionary with keys of Textgrid URIs and values of metadata dictionaries :rtype: dict """ - r = requests.get(self._config.nav_address + "agg/" + - textgrid_uri + "?sid=" + sid) - return self._process_response(r) + response = requests.get(self._config.nav_address + "agg/" + + textgrid_uri + "?sid=" + sid) + return self._process_response(response) def _process_response(self, response: requests.Response) -> dict: """Process the response of a Textgrid Search Service into a dictionary. @@ -132,7 +133,7 @@ class TextgridSearch: tg_results = element_tree.findall("tgs:result", namespaces=namespaces) result_dict = {} for result in tg_results: - result_dict[result.get("textgridUri")] = { + result_dict[result.find("./object/generic/generated/textgridUri", namespaces).text] = { # title^=name, format^=content_type, extent^=content_length "title": result.find("./object/generic/provided/title", namespaces).text, "format": result.find("./object/generic/provided/format", namespaces).text, @@ -141,7 +142,8 @@ class TextgridSearch: return result_dict - def _register_namespaces(self, xml: str) -> dict: + @staticmethod + def _register_namespaces(xml: str) -> dict: """Register namespaces to the global ElementTree and return a dictionary of them. @@ -155,6 +157,7 @@ class TextgridSearch: # create a dictionary containing the namespace prefix and it's uri. The # underscore is utilized to remove the "start-ns" output. `iterparse` # returns an iterator providing (event, elem) pairs. + # see https://medium.datadriveninvestor.com/getting-started-using-pythons-elementtree-to-navigate-xml-files-dc9bc720eaa6 namespaces = {node[0]: node[1] for _, node in ET.iterparse(xml_stream, events=['start-ns'])} @@ -167,6 +170,7 @@ class TextgridSearch: class TextgridCRUD: """Provide access to the Textgrid CRUD Service.""" + def __init__(self): self._config = TextgridConfig() @@ -189,7 +193,8 @@ class TextgridCRUD: return self._process_response(response) def _get_resource(self, sid: str, textgrid_uri: str) -> requests.Response: - """Helper function to get the response headers of a requested resource and defer the download of the message body. + """Helper function to get the response headers of a requested resource + and defer the download of the message body. :param sid: Session ID :type sid: str @@ -200,12 +205,13 @@ class TextgridCRUD: """ uri = self._config.host + DEFAULT_API_VERSION + lookup_api_path("crud") # defer downloading the response body until accessing Response.content - r = requests.get(uri + textgrid_uri + - "/data?sessionId=" + sid, stream=True) + response = requests.get(uri + textgrid_uri + + "/data?sessionId=" + sid, stream=True) # TODO implement error handling on http status not in 200..299 - return r + return response - def _process_response(self, response: requests.Response) -> dict: + @staticmethod + def _process_response(response: requests.Response) -> dict: # only called by `get_metadata` => currently unused result_dict = {} result_dict["content-type"] = response.headers.get("content-type")