Skip to content

Commit e0f7ff1

Browse files
committed
Add "supports" flags for API and APIRequest, lazy load OGC API - Joins conformance
1 parent 086c688 commit e0f7ff1

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

pygeoapi/api/__init__.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ def __init__(self, request, supported_locales):
226226

227227
# Set multipart/form-data using from_* factory methods
228228
self._form = {}
229+
self._supports_formdata = True
229230

230231
# Get path info
231232
if hasattr(request, 'scope'):
@@ -264,7 +265,7 @@ async def from_starlette(cls, request, supported_locales) -> 'APIRequest':
264265
"""
265266
api_req = cls(request, supported_locales)
266267
api_req._data = await request.body()
267-
async for key, value in cls._formdata_starlette(request):
268+
async for key, value in cls._formdata_starlette(api_req, request):
268269
LOGGER.debug(f"Setting form field '{key}'")
269270
if key in api_req._form:
270271
LOGGER.debug(f"Skipping duplicate form field '{key}'")
@@ -308,10 +309,12 @@ def _formdata_django(request):
308309
BytesIO(file_obj.read()))
309310

310311
@staticmethod
311-
async def _formdata_starlette(request):
312+
async def _formdata_starlette(api_req: 'APIRequest', request):
312313
""" Normalize Starlette/FastAPI form data (async). """
313314

314315
if python_multipart is None:
316+
# Set flag so other methods know multipart/form-data is unavailable
317+
api_req._supports_formdata = False
315318
LOGGER.debug('python_multipart is not installed: ' +
316319
'skipping async multipart/form-data')
317320
return
@@ -429,6 +432,15 @@ def form(self) -> dict:
429432
"""Returns the Request form data dict (multipart/form-data)"""
430433
return self._form
431434

435+
@property
436+
def supports_formdata(self) -> bool:
437+
"""
438+
Returns True if the request supports multipart/form-data.
439+
This is unavailable for Starlette/FastAPI if python-multipart
440+
is not installed.
441+
"""
442+
return self._supports_formdata
443+
432444
@property
433445
def params(self) -> dict:
434446
"""Returns the Request query parameters dict"""
@@ -626,6 +638,7 @@ def __init__(self, config: dict, openapi: dict) -> Self | None:
626638
# build reference cache of join tables already/still on the server
627639
self.supports_joins = joins_api.init(config)
628640
else:
641+
# Set flag so other methods know OGC API - Joins is unavailable
629642
self.supports_joins = False
630643

631644
CHARSET[0] = config['server'].get('encoding', 'utf-8')
@@ -897,10 +910,12 @@ def conformance(api: API, request: APIRequest) -> Tuple[dict, int, str]:
897910
apis_dict[provider['type']].CONFORMANCE_CLASSES)
898911
if provider['type'] == 'feature':
899912
conformance_list.extend(
900-
apis_dict['itemtypes'].CONFORMANCE_CLASSES_FEATURES) # noqa
901-
# If there are features, we can also support joins
902-
conformance_list.extend(
903-
apis_dict['joins'].CONFORMANCE_CLASSES)
913+
apis_dict['itemtypes'].CONFORMANCE_CLASSES_FEATURES)
914+
# If it's an OGC API - Features provider and joins is
915+
# supported, we can also add conformance classes for it
916+
if api.supports_joins:
917+
conformance_list.extend(
918+
apis_dict['joins'].CONFORMANCE_CLASSES)
904919
if provider['type'] == 'record':
905920
conformance_list.extend(
906921
apis_dict['itemtypes'].CONFORMANCE_CLASSES_RECORDS)

pygeoapi/api/joins.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,12 @@ def create_join(api: API, request: APIRequest,
850850
headers, collections, dataset = _prepare(api, request, dataset)
851851

852852
if not api.supports_joins:
853-
msg = f'Joins not supported by this API instance'
853+
msg = 'OGC API - Joins is not available on this instance'
854+
return _server_error(api, request, headers, msg)
855+
856+
if not request.supports_formdata:
857+
# i.e. python-multipart library is not installed for Starlette
858+
msg = 'multipart/form-data requests are not supported on this instance'
854859
return _server_error(api, request, headers, msg)
855860

856861
if dataset not in collections:

0 commit comments

Comments
 (0)