You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by bo...@apache.org on 2022/11/12 15:01:30 UTC
[incubator-streampipes] 15/18: tmp
This is an automated email from the ASF dual-hosted git repository.
bossenti pushed a commit to branch feature/STREAMPIPES-607
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
commit e6151d27728fb78e2d42da42b7609cd5401d9623
Author: bossenti <bo...@posteo.de>
AuthorDate: Sat Nov 12 08:22:43 2022 +0100
tmp
---
.../streampipes_client/client/endpoint/endpoint.py | 86 +++++++++++++++++-----
1 file changed, 68 insertions(+), 18 deletions(-)
diff --git a/streampipes-client-python/streampipes_client/client/endpoint/endpoint.py b/streampipes-client-python/streampipes_client/client/endpoint/endpoint.py
index 8547c69bf..a113501b7 100644
--- a/streampipes-client-python/streampipes_client/client/endpoint/endpoint.py
+++ b/streampipes-client-python/streampipes_client/client/endpoint/endpoint.py
@@ -24,7 +24,7 @@ An endpoint is provides all options to communicate with a central endpoint of th
import logging
from abc import ABC, abstractmethod
from http import HTTPStatus
-from typing import Callable, Tuple, Type
+from typing import Callable, Tuple, Type, Union
from requests import Response
from requests.exceptions import BaseHTTPError, HTTPError
@@ -35,9 +35,8 @@ __all__ = ["APIEndpoint"]
logger = logging.getLogger(__name__)
-
# define custom logging messages for some specific HTTP status
-status_code_to_log_message = {
+error_code_to_message = {
401: "\nThe StreamPipes Backend returned an unauthorized error.\n"
"Please check your user name and/or password to be correct.",
403: "\nThere seems to be an issue with the access rights of the given user and the resource you queried.\n"
@@ -74,13 +73,12 @@ class APIEndpoint(ABC):
@property
@abstractmethod
def _relative_api_path(self) -> Tuple[str]:
- """
- Defines the relative api path with regard to the StreamPipes API URL.
+ """Defines the relative api path with regard to the StreamPipes API URL.
Each path within the URL is defined as an own string.
Returns
-------
- A tuple of strings of which every represents a path value of the endpoint's API URL.
+ A tuple of strings of which every represents a path value of the endpoint's API URL.
"""
raise NotImplementedError
@@ -88,39 +86,66 @@ class APIEndpoint(ABC):
@classmethod
@abstractmethod
def _container_cls(cls) -> Type[ModelContainer]:
- """
+ """Defines the model container class the endpoint refers to.
+ This model container class corresponds to thePython data model,
+ which handles multiple resources returned from the endpoint.
Returns
-------
- A class which inherits from `model.ModelContainer`
+ The corresponding container class from the data model,
+ needs to a subclass of `model.ModelContainer`.
"""
raise NotImplementedError
+ @staticmethod
def _make_request(
- self,
- *,
request_method: Callable[..., Response],
url: str,
) -> Response:
+ """Helper method to send requests to the StreamPipes API endpoint.
+ Should be used from methods of this class that interacts with the API, e.g. `all()` and `get()`.
+
+ Parameters
+ ----------
+ request_method: Callable[..., Response]
+ The HTTP method with which to submit the request.
+ Must be one of HTTP methods provided by the `requests` library, e.g. `requests.get`.
+ url: str
+ The full URL to which the request should be applied.
+
+ Returns
+ -------
+ An HTTP response, which is of type `requests.Response` and
+ contains both the actual API response and some metadata.
+ Returned only if the request was successful,
+ otherwise it raises an exception (see `Raises`).
+
+ Raises
+ ------
+ requests.exceptions.HTTPError
+ If the HTTP status code of the error is between `400` and `600`.
+ """
response = request_method(url=url)
+ # check if the API request was successful
try:
response.raise_for_status()
except HTTPError as err:
status_code = err.response.status_code
- log_message = status_code_to_log_message[err.response.status_code]
+ # get custom error message based on the returned status code
+ error_message = error_code_to_message[status_code]
if status_code in [
HTTPStatus.METHOD_NOT_ALLOWED.numerator,
HTTPStatus.NOT_FOUND.numerator,
]:
- log_message += f"url: {err.response.url}\nstatus code: {err.response.status_code}"
+ error_message += f"url: {err.response.url}\nstatus code: {status_code}"
- logger.debug(err.response.text)
- raise HTTPError(log_message) from err
+ logger.debug(f"HTTP error response: {err.response.text}")
+ raise HTTPError(error_message) from err
else:
logger.debug("Successfully retrieved resources from %s.", url)
@@ -128,18 +153,43 @@ class APIEndpoint(ABC):
return response
- def create_api_path(self) -> str:
- return f"{self._parent_client.base_api_path}{'/'.join(api_path for api_path in self._relative_api_path)}"
+ def build_url(self) -> str:
+ """Creates the URL of the API path for the endpoint.
+
+ Returns
+ -------
+ The URL of the Endpoint
+ """
+ return f"{self._parent_client.base_api_path}" f"{'/'.join(api_path for api_path in self._relative_api_path)}"
def all(self) -> ModelContainer:
+ """Get all resources of this endpoint provided by the StreamPipes API.
+ Results are provided as an instance of a `model.ModelContainer` that
+ allows to handle the returned resources in a comfortable and pythonic way.
+
+ Returns
+ -------
+ A model container instance (`model.ModelContainer`) bundling the resources returned.
+ """
response = self._make_request(
request_method=self._parent_client.request_session.get,
- url=self.create_api_path(),
+ url=self.build_url(),
)
return self._container_cls().from_json(json_string=response.text)
- def get(self, *, identifier: str) -> Element:
+ def get(self, identifier: str) -> Element:
+ """Queries the specified resource from the API endpoint.
+
+ Parameters
+ ----------
+ identifier: str
+ The identifier of the resource to be queried.
+
+ Returns
+ -------
+ The specified resource as an instance of the corresponding model class (`model.Element`).
+ """
# equals to download
# needs further considerations