Skip to content

Commit 00dcb3d

Browse files
Merge pull request #28 from Geovation/feat/docs
Feat/docs
2 parents ad57a6d + bc52aaa commit 00dcb3d

9 files changed

Lines changed: 110859 additions & 56 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.env
22
.venv
33
**/.DS_Store
4-
src/catalyst_ngd_wrappers/__pycache__
4+
src/catalyst_ngd_wrappers/__pycache__
5+
src/catalyst_ngd_wrappers/test.ipynb

README.md

Lines changed: 169 additions & 9 deletions
Large diffs are not rendered by default.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
requires = ["setuptools"]
33
build-backend = "setuptools.build_meta"
44

5-
[metadata]
5+
[project]
66
name = "catalyst_ngd_wrappers"
77
version = "0.4.0"
88
requires-python = ">=3.11"

src/catalyst_ngd_wrappers/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
'items_geom',
2020
'items_col',
2121
'items_limit_geom',
22-
'items_col_geom',
23-
'items_col_limit',
24-
'items_col_limit_geom'
22+
'items_limit_col',
23+
'items_geom_col',
24+
'items_limit_geom_col'
2525
]

src/catalyst_ngd_wrappers/ngd_api_wrappers.py

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
from shapely import from_wkt
2323
from shapely.errors import GEOSException
2424

25-
from .utils import prepare_parameters, handle_decode_error, multilevel_explode
26-
from .telemetry import prepare_telemetry_custom_dimensions
25+
from utils import prepare_parameters, handle_decode_error, multilevel_explode, construct_error_response
26+
from telemetry import prepare_telemetry_custom_dimensions
2727

2828
UNIVERSAL_TIMEOUT: int = 20
2929
RETRIES: int = 3
@@ -124,13 +124,11 @@ def get_specific_latest_collections(collection: list[str], **kwargs) -> str:
124124
specific_latest_collections = {
125125
col: latest_collections[col] for col in collection}
126126
except KeyError as e:
127-
return {
128-
'code': 404,
129-
'description': f'Collection {e} is not a supported Collection base name. The name must not include a version suffix. Please refer to the documentation for a list of supported Collections.',
130-
'help': 'https://api.os.uk/features/ngd/ofa/v1/collections',
131-
'errorSource': 'Catalyst Wrapper'
132-
}
133-
127+
return construct_error_response(
128+
status_code = 404,
129+
message = f'Collection {e} is not a supported Collection base name. The name must not include a version suffix. Please refer to the documentation for a list of supported Collections.',
130+
help_text = 'https://api.os.uk/features/ngd/ofa/v1/collections'
131+
)
134132
return specific_latest_collections
135133

136134

@@ -228,11 +226,10 @@ def run_request(headers_: dict) -> dict:
228226
client_secret=client_secret
229227
)
230228
except PermissionError:
231-
return {
232-
'code': 401,
233-
'description': 'Missing or invalid CLIENT_ID and/or CLIENT_SECRET. Make sure these are configured correctely in your environment variables.',
234-
'errorSource': 'Catalyst Wrapper'
235-
}
229+
return construct_error_response(
230+
status_code = 401,
231+
message = 'Missing or invalid CLIENT_ID and/or CLIENT_SECRET. Make sure these are configured correctely in your environment variables.'
232+
)
236233
os.environ['ACCESS_TOKEN'] = access_token
237234
headers['Authorization'] = f'Bearer {access_token}'
238235
return run_request(headers)
@@ -272,22 +269,24 @@ def ngd_items_request(
272269
) -> dict:
273270
'''
274271
Calls items from the OS NGD API - Features
275-
- https://osdatahub.os.uk/docs/wfs/overview
272+
- https://www.ordnancesurvey.co.uk/products/os-ngd-api-features
276273
- https://docs.os.uk/osngd/accessing-os-ngd/access-the-os-ngd-api/os-ngd-api-features
277274
Parameters:
278-
collection (str) - the feature collection to call from. Feature collection names and details can be found at https://api.os.uk/features/ngd/ofa/v1/collections/
279-
params (dict, optional) - parameters to pass to the query as query parameters, supplied in a dictionary. Supported parameters are: bbox, bbox-crs, crs, datetime, filter, filter-crs, filter-lang, limit, offset
275+
collection (str) - The feature collection to call from. Feature collection names and details can be found at https://api.os.uk/features/ngd/ofa/v1/collections/
276+
params (dict, optional) - Parameters to pass to the API request as query parameters, supplied in a dictionary. Supported parameters are: bbox, bbox-crs, crs, datetime, filter, filter-crs, filter-lang, limit, offset. Find details of these API parameters on the OS technical docs: https://docs.os.uk/osngd/getting-started/access-the-os-ngd-api/os-ngd-api-features/technical-specification/features#get-collections-collectionid-items.
280277
filter_params (dict, optional) - OS NGD attribute filters to pass to the query within the 'filter' query_param. The can be used instead of or in addition to manually setting the filter in params.
281278
The key-value pairs will appended using the EQUAL TO [ = ] comparator. Any other CQL Operator comparisons must be set manually in params.
282279
Queryable attributes can be found in OS NGD codelists documentation https://docs.os.uk/osngd/code-lists/code-lists-overview, or by inserting the relevant collectionId into the https://api.os.uk/features/ngd/ofa/v1/collections/{{collectionId}}/queryables endpoint.
283280
wkt (string or shapely geometry object) - A means of searching a geometry for features. The search area(s) must be supplied in wkt, either in a string or as a Shapely geometry object.
284281
The function automatically composes the full INTERSECTS filter and adds it to the 'filter' query parameter.
285282
Make sure that 'filter-crs' is set to the appropriate value.
283+
authenticate (boolean, default True) - If True, the request is authenticated using OAuth2. This requires the CLIENT_ID and CLIENT_SECRET environment variables to be set.
284+
If False, no authentication is used, and an API key must be supplied in either the headers or params.
285+
log_request_details (boolean, default True) - If True, adds extra logging for the request details. This can be used for telemetry when deployed as an API.
286286
use_latest_collection (boolean, default False) - If True, it ensures that if a specific version of a collection is not supplied (eg. bld-fts-building[-2]), the latest version is used.
287287
Note that if use_latest_collection but 'collection' does specify a version, the specified version is always used regardless of use_latest_collection.
288288
headers (dict, optional) - Headers to pass to the query. These can include bearer-token authentication.
289-
access_token (str) - An access token, which will be added as bearer token to the headers.
290-
**kwargs: other generic parameters to be passed to the requests.get()
289+
**kwargs - other parameters to be passed to the request.Session.request get method eg. headers, timeout.
291290
292291
Returns the features as a geojson, as per the OS NGD API.
293292
'''
@@ -370,12 +369,15 @@ def wrapper(
370369

371370
params = params.copy() if params else {}
372371

372+
if 'limit' in params:
373+
return construct_error_response(
374+
message = "With this Catalyst wrapper, the limit must be supplied as a function parameter and not as a key-value pair in params.",
375+
)
376+
373377
if 'offset' in params:
374-
return {
375-
'code': 400,
376-
'description': "'offset' is not a valid attribute for functions using this Catalyst wrapper.",
377-
'errorSource': 'Catalyst Wrapper'
378-
}
378+
return construct_error_response(
379+
message = "'offset' is not a valid attribute for functions using this Catalyst wrapper.",
380+
)
379381

380382
features = []
381383

@@ -385,11 +387,9 @@ def wrapper(
385387
offset = 0
386388

387389
if not limit and not request_limit:
388-
return {
389-
'code': 400,
390-
'description': 'At least one of limit or request_limit must be provided to prevent indefinitely numerous requests and high costs.',
391-
'errorSource': 'Catalyst Wrapper'
392-
}
390+
return construct_error_response(
391+
message = 'At least one of limit or request_limit must be provided to prevent indefinitely numerous requests and high costs.'
392+
)
393393

394394
while (request_count != request_limit) and (not (limit) or offset < limit):
395395

@@ -502,12 +502,10 @@ def wrapper(
502502
try:
503503
full_geom = from_wkt(wkt) if isinstance(wkt, str) else wkt
504504
except GEOSException:
505-
return {
506-
'code': 400,
507-
'description': 'The input geometry is not valid. Please ensure you have the correct formatting for your input geometry type.',
508-
'help': 'http://libgeos.org/specifications/wkt/',
509-
'errorSource': 'Catalyst Wrapper'
510-
}
505+
return construct_error_response(
506+
message = 'The input geometry is not valid. Please ensure you have the correct formatting for your input geometry type.',
507+
help = 'http://libgeos.org/specifications/wkt/',
508+
)
511509

512510
search_areas = []
513511
partial_geoms = multilevel_explode(full_geom)

src/catalyst_ngd_wrappers/telemetry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import os
66

7-
from .utils import flatten_coords
7+
from utils import flatten_coords
88

99
QUERY_PARAM_TELEMETRY_LENGTH_LIMIT: int = int(
1010
os.environ.get('QUERY_PARAM_TELEMETRY_LENGTH_LIMIT', '200'))

0 commit comments

Comments
 (0)