From 50dd565b8cde0848606f2541ac4bb3ccd3e04ac9 Mon Sep 17 00:00:00 2001 From: Christina Ludwig Date: Fri, 4 Jun 2021 10:32:06 +0200 Subject: [PATCH 1/5] update version to 0.1.0rc1 (#67) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 13744be..2066059 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ohsome" -version = "0.1.0rc" +version = "0.1.0rc1" description = "A Python client for the ohsome API" authors = ["Christina Ludwig "] readme = 'README.md' From fde8dd57678f6a0620e63b3c3ded690b7e8b3187 Mon Sep 17 00:00:00 2001 From: Moritz Schott Date: Mon, 7 Jun 2021 13:45:21 +0200 Subject: [PATCH 2/5] Fix logging for broken requests (#69) * relax pre-commit to use any python3 version * make logging of raw response more robust * ensure correct checking of 'is response present?' and switch test value to match expected and actual order --- .pre-commit-config.yaml | 2 +- ohsome/exceptions.py | 3 ++- ohsome/test/test_exceptions.py | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b537c87..1342d59 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: rev: stable hooks: - id: black - language_version: python3.9 + language_version: python3 - repo: https://gitlab.com/pycqa/flake8 rev: 3.8.4 hooks: diff --git a/ohsome/exceptions.py b/ohsome/exceptions.py index efba589..427edc9 100644 --- a/ohsome/exceptions.py +++ b/ohsome/exceptions.py @@ -32,7 +32,8 @@ def log(self, log_dir): log_file_name = f"ohsome_{dt.datetime.now().strftime('%Y-%m-%dT%H%M%S')}" self.log_bpolys(log_dir, log_file_name) self.log_parameter(log_dir, log_file_name) - self.log_response(log_dir, log_file_name) + if self.response is not None: + self.log_response(log_dir, log_file_name) # self.log_query(log_dir, log_file_name) def log_response(self, log_dir, log_file_name): diff --git a/ohsome/test/test_exceptions.py b/ohsome/test/test_exceptions.py index 10be5d9..5d71cad 100644 --- a/ohsome/test/test_exceptions.py +++ b/ohsome/test/test_exceptions.py @@ -88,7 +88,7 @@ def test_disable_logging(custom_client): if os.path.exists(custom_client.log_dir): n_log_files_after = len(os.listdir(custom_client.log_dir)) - assert n_log_files_before == n_log_files_after + assert n_log_files_after == n_log_files_before def test_enable_logging(custom_client_without_log, tmpdir): @@ -110,7 +110,7 @@ def test_enable_logging(custom_client_without_log, tmpdir): ) n_log_files_after = len(os.listdir(custom_client_without_log.log_dir)) - assert n_log_files_before + 2 == n_log_files_after + assert n_log_files_after == n_log_files_before + 2 def test_log_bpolys(custom_client_without_log, tmpdir): @@ -134,7 +134,7 @@ def test_log_bpolys(custom_client_without_log, tmpdir): bpolys=bpolys, time=time, filter=fltr, timeout=timeout ) n_log_files_after = len(os.listdir(custom_client_without_log.log_dir)) - assert n_log_files_before + 3 == n_log_files_after + assert n_log_files_after == n_log_files_before + 3 def test_metadata_invalid_baseurl(custom_client_with_wrong_url): From 41ac92162d9cd1b6b2c4cc4fd9c6a073958088af Mon Sep 17 00:00:00 2001 From: Moritz Schott Date: Wed, 9 Jun 2021 13:21:04 +0200 Subject: [PATCH 3/5] add test for empty response (#70) * relax pre-commit to use any python3 version * make logging of raw response more robust * ensure correct checking of 'is response present?' and switch test value to match expected and actual order * add test for empty response * use correct syntax for conda verisons --- README.md | 2 +- ohsome/test/test_exceptions.py | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e1ce7d8..ff6bf02 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ $ pip install ohsome *ohsome-py* is not available through Anaconda yet. So if you are using Anaconda, create a new anaconda environment and install the required dependencies before installing *ohsome-py* using pip. Please note that there might be issues when [using pip within anaconda](https://www.anaconda.com/blog/using-pip-in-a-conda-environment). To avoid issues make sure to install everythin in a new conda environment. ``` -$ conda create -n ohsome python=3.8 geopandas>=0.9.0 requests>=2.25.1 +$ conda create -n ohsome python=3.8 geopandas">=0.9.0" requests">=2.25.1" $ conda activate ohsome $ pip install ohsome --no-deps ``` diff --git a/ohsome/test/test_exceptions.py b/ohsome/test/test_exceptions.py index 5d71cad..d2e2cdc 100644 --- a/ohsome/test/test_exceptions.py +++ b/ohsome/test/test_exceptions.py @@ -7,6 +7,8 @@ import logging import geopandas as gpd import ohsome +from unittest.mock import patch, MagicMock +from requests.exceptions import RequestException script_path = os.path.dirname(os.path.realpath(__file__)) logger = logging.getLogger(__name__) @@ -161,3 +163,28 @@ def test_exception_invalid_parameters(custom_client): bboxes=bboxes, time=time, filter=fltr ) "You need to give one groupByKey parameter" in e_info.value.message + + +def test_exception_connection_reset(custom_client): + """ + Test whether error without response (e.g. connection reset) is handled correctly + :param custom_client: + :return: + """ + + with patch( + "requests.Response.raise_for_status", + MagicMock( + side_effect=RequestException( + "This request was failed on purpose without response!" + ) + ), + ), patch("ohsome.OhsomeException.log_response", MagicMock()) as mock_func: + bpolys = gpd.read_file(f"{script_path}/data/polygons.geojson") + time = "2018-01-01" + fltr = "name=Krautturm and type:way" + + with pytest.raises(ohsome.OhsomeException): + custom_client.elements.count.post(bpolys=bpolys, time=time, filter=fltr) + + mock_func.assert_not_called() From ff21d4d3a2c39567629bfd7fdaa6781e46adee9b Mon Sep 17 00:00:00 2001 From: Johannes Visintini Date: Tue, 27 Jul 2021 19:17:28 +0200 Subject: [PATCH 4/5] set user-agent specific for the client (#73) * set user-agent specific for the client closes #72 * update version to 0.1.0rc2 --- ohsome/clients.py | 41 ++++++++++++++++++++++++++++++++------ ohsome/constants.py | 2 ++ ohsome/test/test_client.py | 14 +++++++++++++ pyproject.toml | 3 ++- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/ohsome/clients.py b/ohsome/clients.py index fde689e..29a71ec 100644 --- a/ohsome/clients.py +++ b/ohsome/clients.py @@ -6,7 +6,12 @@ import requests from ohsome import OhsomeException, OhsomeResponse -from ohsome.constants import DEFAULT_LOG_DIR, DEFAULT_LOG, OHSOME_BASE_API_URL +from ohsome.constants import ( + DEFAULT_LOG_DIR, + DEFAULT_LOG, + OHSOME_BASE_API_URL, + OHSOME_VERSION, +) from ohsome.helper import ( extract_error_message_from_invalid_json, format_boundary, @@ -19,7 +24,12 @@ class _OhsomeBaseClient: def __init__( - self, base_api_url=None, log=DEFAULT_LOG, log_dir=DEFAULT_LOG_DIR, cache=None + self, + base_api_url=None, + log=DEFAULT_LOG, + log_dir=DEFAULT_LOG_DIR, + cache=None, + user_agent=None, ): """ Initialize _OhsomeInfoClient object @@ -38,6 +48,10 @@ def __init__( else: self._base_api_url = OHSOME_BASE_API_URL self._cache = cache or [] + if user_agent is not None: + self.user_agent = user_agent + else: + self.user_agent = "ohsome-py/{0}".format(OHSOME_VERSION) self.__session = None def _session(self): @@ -56,6 +70,7 @@ def _session(self): self.__session = requests.Session() self.__session.mount("https://", adapter) self.__session.mount("http://", adapter) + self.__session.headers["user-agent"] = self.user_agent return self.__session def __repr__(self): @@ -66,7 +81,12 @@ class _OhsomeInfoClient(_OhsomeBaseClient): """Client for metadata of ohsome API""" def __init__( - self, base_api_url=None, log=DEFAULT_LOG, log_dir=DEFAULT_LOG_DIR, cache=None + self, + base_api_url=None, + log=DEFAULT_LOG, + log_dir=DEFAULT_LOG_DIR, + cache=None, + user_agent=None, ): """ Initialize _OhsomeInfoClient object @@ -75,7 +95,9 @@ def __init__( :param log_dir: Directory for log files, default: ./ohsome_log :param cache: Cache for endpoint components """ - super(_OhsomeInfoClient, self).__init__(base_api_url, log, log_dir, cache) + super(_OhsomeInfoClient, self).__init__( + base_api_url, log, log_dir, cache, user_agent + ) self._parameters = None self._metadata = None self._url = None @@ -154,7 +176,12 @@ class _OhsomePostClient(_OhsomeBaseClient): """Client for sending requests to ohsome API""" def __init__( - self, base_api_url=None, log=DEFAULT_LOG, log_dir=DEFAULT_LOG_DIR, cache=None + self, + base_api_url=None, + log=DEFAULT_LOG, + log_dir=DEFAULT_LOG_DIR, + cache=None, + user_agent=None, ): """ Initialize _OhsomePostClient object @@ -163,7 +190,9 @@ def __init__( :param log_dir: Directory for log files, default: ./ohsome_log :param cache: Cache for endpoint components """ - super(_OhsomePostClient, self).__init__(base_api_url, log, log_dir, cache) + super(_OhsomePostClient, self).__init__( + base_api_url, log, log_dir, cache, user_agent + ) self._parameters = None self._metadata = None self._url = None diff --git a/ohsome/constants.py b/ohsome/constants.py index f9b07d4..be1ebfb 100644 --- a/ohsome/constants.py +++ b/ohsome/constants.py @@ -5,3 +5,5 @@ OHSOME_BASE_API_URL = "https://api.ohsome.org/v1/" DEFAULT_LOG = True DEFAULT_LOG_DIR = "./ohsome_log" +# update version in pyproject.toml as well +OHSOME_VERSION = "0.1.0rc2" diff --git a/ohsome/test/test_client.py b/ohsome/test/test_client.py index ce297fd..76e96c2 100644 --- a/ohsome/test/test_client.py +++ b/ohsome/test/test_client.py @@ -11,6 +11,7 @@ import pytest import ohsome +from ohsome.constants import OHSOME_VERSION script_path = os.path.dirname(os.path.realpath(__file__)) logger = logging.getLogger(__name__) @@ -58,6 +59,19 @@ def test_api_version(custom_client): assert isinstance(custom_client.api_version, str) +def test_user_agent(custom_client): + """ + Checks user agent set by ohsome-py + :return: + """ + client = custom_client + resp = client._session().get(client._url) + print(resp.request.headers) + used_user_agent = resp.request.headers["user-agent"].split("/") + assert used_user_agent[0] == "ohsome-py" + assert used_user_agent[1] == OHSOME_VERSION + + def test_check_time_parameter_list(custom_client): """ Checks whether time provided as list of strings is converted correctly diff --git a/pyproject.toml b/pyproject.toml index 2066059..6bb61a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,7 @@ [tool.poetry] name = "ohsome" -version = "0.1.0rc1" +# update version in ohsome/constants.py as well +version = "0.1.0rc2" description = "A Python client for the ohsome API" authors = ["Christina Ludwig "] readme = 'README.md' From e06e3d2f6b7280a2780cbf415eb73b01c1175492 Mon Sep 17 00:00:00 2001 From: Christina Ludwig Date: Wed, 15 Sep 2021 12:41:31 +0200 Subject: [PATCH 5/5] add support for ndarrays as input parameter (#74) --- ohsome/clients.py | 4 ++++ ohsome/test/test_client.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ohsome/clients.py b/ohsome/clients.py index 29a71ec..c152edd 100644 --- a/ohsome/clients.py +++ b/ohsome/clients.py @@ -20,6 +20,7 @@ import os from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.retry import Retry +import numpy as np class _OhsomeBaseClient: @@ -345,6 +346,9 @@ def _format_parameters(self, params): :param params: Parameters for request :return: """ + for i in params.keys(): + if isinstance(params[i], np.ndarray): + params[i] = list(params[i]) self._parameters = params.copy() try: format_boundary(self._parameters) diff --git a/ohsome/test/test_client.py b/ohsome/test/test_client.py index 76e96c2..4691bae 100644 --- a/ohsome/test/test_client.py +++ b/ohsome/test/test_client.py @@ -9,6 +9,7 @@ import geopandas as gpd import pandas as pd import pytest +import numpy as np import ohsome from ohsome.constants import OHSOME_VERSION @@ -341,6 +342,21 @@ def test_format_bboxes_list(custom_client): client.elements.count.post(bboxes=bboxes, time=time, filter=fltr) +def test_bbox_numpy(custom_client): + """ + Tests whether numpy arrays are supported as input parameters + :return: + """ + + time = "2010-01-01" + fltr = "amenity=restaurant and type:node" + + client = custom_client + + bboxes = np.array([8.67066, 49.41423, 8.68177, 49.4204]) + client.elements.count.post(bboxes=bboxes, time=time, filter=fltr) + + def test_post_with_endpoint_string(custom_client): """ Tests whether a request can be sent of by providing the endpoint url as a string to post()