Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
redfrexx committed Oct 15, 2021
2 parents b405c74 + 833a282 commit 317059d
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand Down
45 changes: 39 additions & 6 deletions ohsome/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -15,11 +20,17 @@
import os
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
import numpy as np


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
Expand All @@ -38,6 +49,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):
Expand All @@ -56,6 +71,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):
Expand All @@ -66,7 +82,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
Expand All @@ -75,7 +96,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
Expand Down Expand Up @@ -154,7 +177,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
Expand All @@ -163,7 +191,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
Expand Down Expand Up @@ -316,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)
Expand Down
2 changes: 2 additions & 0 deletions ohsome/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
3 changes: 2 additions & 1 deletion ohsome/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
30 changes: 30 additions & 0 deletions ohsome/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import geopandas as gpd
import pandas as pd
import pytest
import numpy as np

import ohsome
from ohsome.constants import OHSOME_VERSION

script_path = os.path.dirname(os.path.realpath(__file__))
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -58,6 +60,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
Expand Down Expand Up @@ -327,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()
Expand Down
33 changes: 30 additions & 3 deletions ohsome/test/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand Down Expand Up @@ -88,7 +90,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):
Expand All @@ -110,7 +112,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):
Expand All @@ -134,7 +136,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):
Expand All @@ -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()
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "ohsome"
version = "0.1.0rc1"
version = "0.1.0rc2"
description = "A Python client for the ohsome API"
authors = ["Christina Ludwig <[email protected]>"]
readme = 'README.md'
Expand Down

0 comments on commit 317059d

Please sign in to comment.