Skip to content

Commit 317059d

Browse files
committed
Merge branch 'development'
2 parents b405c74 + 833a282 commit 317059d

File tree

8 files changed

+106
-13
lines changed

8 files changed

+106
-13
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ repos:
33
rev: stable
44
hooks:
55
- id: black
6-
language_version: python3.9
6+
language_version: python3
77
- repo: https://gitlab.com/pycqa/flake8
88
rev: 3.8.4
99
hooks:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ $ pip install ohsome
2828
*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.
2929

3030
```
31-
$ conda create -n ohsome python=3.8 geopandas>=0.9.0 requests>=2.25.1
31+
$ conda create -n ohsome python=3.8 geopandas">=0.9.0" requests">=2.25.1"
3232
$ conda activate ohsome
3333
$ pip install ohsome --no-deps
3434
```

ohsome/clients.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66

77
import requests
88
from ohsome import OhsomeException, OhsomeResponse
9-
from ohsome.constants import DEFAULT_LOG_DIR, DEFAULT_LOG, OHSOME_BASE_API_URL
9+
from ohsome.constants import (
10+
DEFAULT_LOG_DIR,
11+
DEFAULT_LOG,
12+
OHSOME_BASE_API_URL,
13+
OHSOME_VERSION,
14+
)
1015
from ohsome.helper import (
1116
extract_error_message_from_invalid_json,
1217
format_boundary,
@@ -15,11 +20,17 @@
1520
import os
1621
from requests.adapters import HTTPAdapter
1722
from requests.packages.urllib3.util.retry import Retry
23+
import numpy as np
1824

1925

2026
class _OhsomeBaseClient:
2127
def __init__(
22-
self, base_api_url=None, log=DEFAULT_LOG, log_dir=DEFAULT_LOG_DIR, cache=None
28+
self,
29+
base_api_url=None,
30+
log=DEFAULT_LOG,
31+
log_dir=DEFAULT_LOG_DIR,
32+
cache=None,
33+
user_agent=None,
2334
):
2435
"""
2536
Initialize _OhsomeInfoClient object
@@ -38,6 +49,10 @@ def __init__(
3849
else:
3950
self._base_api_url = OHSOME_BASE_API_URL
4051
self._cache = cache or []
52+
if user_agent is not None:
53+
self.user_agent = user_agent
54+
else:
55+
self.user_agent = "ohsome-py/{0}".format(OHSOME_VERSION)
4156
self.__session = None
4257

4358
def _session(self):
@@ -56,6 +71,7 @@ def _session(self):
5671
self.__session = requests.Session()
5772
self.__session.mount("https://", adapter)
5873
self.__session.mount("http://", adapter)
74+
self.__session.headers["user-agent"] = self.user_agent
5975
return self.__session
6076

6177
def __repr__(self):
@@ -66,7 +82,12 @@ class _OhsomeInfoClient(_OhsomeBaseClient):
6682
"""Client for metadata of ohsome API"""
6783

6884
def __init__(
69-
self, base_api_url=None, log=DEFAULT_LOG, log_dir=DEFAULT_LOG_DIR, cache=None
85+
self,
86+
base_api_url=None,
87+
log=DEFAULT_LOG,
88+
log_dir=DEFAULT_LOG_DIR,
89+
cache=None,
90+
user_agent=None,
7091
):
7192
"""
7293
Initialize _OhsomeInfoClient object
@@ -75,7 +96,9 @@ def __init__(
7596
:param log_dir: Directory for log files, default: ./ohsome_log
7697
:param cache: Cache for endpoint components
7798
"""
78-
super(_OhsomeInfoClient, self).__init__(base_api_url, log, log_dir, cache)
99+
super(_OhsomeInfoClient, self).__init__(
100+
base_api_url, log, log_dir, cache, user_agent
101+
)
79102
self._parameters = None
80103
self._metadata = None
81104
self._url = None
@@ -154,7 +177,12 @@ class _OhsomePostClient(_OhsomeBaseClient):
154177
"""Client for sending requests to ohsome API"""
155178

156179
def __init__(
157-
self, base_api_url=None, log=DEFAULT_LOG, log_dir=DEFAULT_LOG_DIR, cache=None
180+
self,
181+
base_api_url=None,
182+
log=DEFAULT_LOG,
183+
log_dir=DEFAULT_LOG_DIR,
184+
cache=None,
185+
user_agent=None,
158186
):
159187
"""
160188
Initialize _OhsomePostClient object
@@ -163,7 +191,9 @@ def __init__(
163191
:param log_dir: Directory for log files, default: ./ohsome_log
164192
:param cache: Cache for endpoint components
165193
"""
166-
super(_OhsomePostClient, self).__init__(base_api_url, log, log_dir, cache)
194+
super(_OhsomePostClient, self).__init__(
195+
base_api_url, log, log_dir, cache, user_agent
196+
)
167197
self._parameters = None
168198
self._metadata = None
169199
self._url = None
@@ -316,6 +346,9 @@ def _format_parameters(self, params):
316346
:param params: Parameters for request
317347
:return:
318348
"""
349+
for i in params.keys():
350+
if isinstance(params[i], np.ndarray):
351+
params[i] = list(params[i])
319352
self._parameters = params.copy()
320353
try:
321354
format_boundary(self._parameters)

ohsome/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
OHSOME_BASE_API_URL = "https://api.ohsome.org/v1/"
66
DEFAULT_LOG = True
77
DEFAULT_LOG_DIR = "./ohsome_log"
8+
# update version in pyproject.toml as well
9+
OHSOME_VERSION = "0.1.0rc2"

ohsome/exceptions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def log(self, log_dir):
3232
log_file_name = f"ohsome_{dt.datetime.now().strftime('%Y-%m-%dT%H%M%S')}"
3333
self.log_bpolys(log_dir, log_file_name)
3434
self.log_parameter(log_dir, log_file_name)
35-
self.log_response(log_dir, log_file_name)
35+
if self.response is not None:
36+
self.log_response(log_dir, log_file_name)
3637
# self.log_query(log_dir, log_file_name)
3738

3839
def log_response(self, log_dir, log_file_name):

ohsome/test/test_client.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
import geopandas as gpd
1010
import pandas as pd
1111
import pytest
12+
import numpy as np
1213

1314
import ohsome
15+
from ohsome.constants import OHSOME_VERSION
1416

1517
script_path = os.path.dirname(os.path.realpath(__file__))
1618
logger = logging.getLogger(__name__)
@@ -58,6 +60,19 @@ def test_api_version(custom_client):
5860
assert isinstance(custom_client.api_version, str)
5961

6062

63+
def test_user_agent(custom_client):
64+
"""
65+
Checks user agent set by ohsome-py
66+
:return:
67+
"""
68+
client = custom_client
69+
resp = client._session().get(client._url)
70+
print(resp.request.headers)
71+
used_user_agent = resp.request.headers["user-agent"].split("/")
72+
assert used_user_agent[0] == "ohsome-py"
73+
assert used_user_agent[1] == OHSOME_VERSION
74+
75+
6176
def test_check_time_parameter_list(custom_client):
6277
"""
6378
Checks whether time provided as list of strings is converted correctly
@@ -327,6 +342,21 @@ def test_format_bboxes_list(custom_client):
327342
client.elements.count.post(bboxes=bboxes, time=time, filter=fltr)
328343

329344

345+
def test_bbox_numpy(custom_client):
346+
"""
347+
Tests whether numpy arrays are supported as input parameters
348+
:return:
349+
"""
350+
351+
time = "2010-01-01"
352+
fltr = "amenity=restaurant and type:node"
353+
354+
client = custom_client
355+
356+
bboxes = np.array([8.67066, 49.41423, 8.68177, 49.4204])
357+
client.elements.count.post(bboxes=bboxes, time=time, filter=fltr)
358+
359+
330360
def test_post_with_endpoint_string(custom_client):
331361
"""
332362
Tests whether a request can be sent of by providing the endpoint url as a string to post()

ohsome/test/test_exceptions.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import logging
88
import geopandas as gpd
99
import ohsome
10+
from unittest.mock import patch, MagicMock
11+
from requests.exceptions import RequestException
1012

1113
script_path = os.path.dirname(os.path.realpath(__file__))
1214
logger = logging.getLogger(__name__)
@@ -88,7 +90,7 @@ def test_disable_logging(custom_client):
8890

8991
if os.path.exists(custom_client.log_dir):
9092
n_log_files_after = len(os.listdir(custom_client.log_dir))
91-
assert n_log_files_before == n_log_files_after
93+
assert n_log_files_after == n_log_files_before
9294

9395

9496
def test_enable_logging(custom_client_without_log, tmpdir):
@@ -110,7 +112,7 @@ def test_enable_logging(custom_client_without_log, tmpdir):
110112
)
111113

112114
n_log_files_after = len(os.listdir(custom_client_without_log.log_dir))
113-
assert n_log_files_before + 2 == n_log_files_after
115+
assert n_log_files_after == n_log_files_before + 2
114116

115117

116118
def test_log_bpolys(custom_client_without_log, tmpdir):
@@ -134,7 +136,7 @@ def test_log_bpolys(custom_client_without_log, tmpdir):
134136
bpolys=bpolys, time=time, filter=fltr, timeout=timeout
135137
)
136138
n_log_files_after = len(os.listdir(custom_client_without_log.log_dir))
137-
assert n_log_files_before + 3 == n_log_files_after
139+
assert n_log_files_after == n_log_files_before + 3
138140

139141

140142
def test_metadata_invalid_baseurl(custom_client_with_wrong_url):
@@ -161,3 +163,28 @@ def test_exception_invalid_parameters(custom_client):
161163
bboxes=bboxes, time=time, filter=fltr
162164
)
163165
"You need to give one groupByKey parameter" in e_info.value.message
166+
167+
168+
def test_exception_connection_reset(custom_client):
169+
"""
170+
Test whether error without response (e.g. connection reset) is handled correctly
171+
:param custom_client:
172+
:return:
173+
"""
174+
175+
with patch(
176+
"requests.Response.raise_for_status",
177+
MagicMock(
178+
side_effect=RequestException(
179+
"This request was failed on purpose without response!"
180+
)
181+
),
182+
), patch("ohsome.OhsomeException.log_response", MagicMock()) as mock_func:
183+
bpolys = gpd.read_file(f"{script_path}/data/polygons.geojson")
184+
time = "2018-01-01"
185+
fltr = "name=Krautturm and type:way"
186+
187+
with pytest.raises(ohsome.OhsomeException):
188+
custom_client.elements.count.post(bpolys=bpolys, time=time, filter=fltr)
189+
190+
mock_func.assert_not_called()

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "ohsome"
3-
version = "0.1.0rc1"
3+
version = "0.1.0rc2"
44
description = "A Python client for the ohsome API"
55
authors = ["Christina Ludwig <[email protected]>"]
66
readme = 'README.md'

0 commit comments

Comments
 (0)