"""
Server implementation using the falcon webserver framework.
"""
-from typing import Optional, Mapping, cast, Any, List
+from typing import Optional, Mapping, Any, List
from pathlib import Path
import datetime as dt
import asyncio
from ...config import Configuration
from ...core import NominatimAPIAsync
from ... import v1 as api_impl
+from ...result_formatting import FormatDispatcher, load_format_dispatcher
from ... import logging as loglib
+from ..asgi_adaptor import ASGIAdaptor, EndpointFunc
class HTTPNominatimError(Exception):
""" A special exception class for errors raised during processing.
resp.content_type = 'text/plain; charset=utf-8'
-class ParamWrapper(api_impl.ASGIAdaptor):
+class ParamWrapper(ASGIAdaptor):
""" Adaptor class for server glue to Falcon framework.
"""
def __init__(self, req: Request, resp: Response,
- config: Configuration) -> None:
+ config: Configuration, formatter: FormatDispatcher) -> None:
self.request = req
self.response = resp
self._config = config
+ self._formatter = formatter
def get(self, name: str, default: Optional[str] = None) -> Optional[str]:
- return cast(Optional[str], self.request.get_param(name, default=default))
+ return self.request.get_param(name, default=default)
def get_header(self, name: str, default: Optional[str] = None) -> Optional[str]:
- return cast(Optional[str], self.request.get_header(name, default=default))
+ return self.request.get_header(name, default=default)
def error(self, msg: str, status: int = 400) -> HTTPNominatimError:
def base_uri(self) -> str:
- return cast (str, self.request.forwarded_prefix)
+ return self.request.forwarded_prefix
def config(self) -> Configuration:
return self._config
+ def formatting(self) -> FormatDispatcher:
+ return self._formatter
+
class EndpointWrapper:
""" Converter for server glue endpoint functions to Falcon request handlers.
"""
- def __init__(self, name: str, func: api_impl.EndpointFunc, api: NominatimAPIAsync) -> None:
+ def __init__(self, name: str, func: EndpointFunc, api: NominatimAPIAsync,
+ formatter: FormatDispatcher) -> None:
self.name = name
self.func = func
self.api = api
+ self.formatter = formatter
async def on_get(self, req: Request, resp: Response) -> None:
""" Implementation of the endpoint.
"""
- await self.func(self.api, ParamWrapper(req, resp, self.api.config))
+ await self.func(self.api, ParamWrapper(req, resp, self.api.config,
+ self.formatter))
class FileLoggingMiddleware:
app.add_error_handler(HTTPNominatimError, nominatim_error_handler)
app.add_error_handler(TimeoutError, timeout_error_handler)
# different from TimeoutError in Python <= 3.10
- app.add_error_handler(asyncio.TimeoutError, timeout_error_handler)
+ app.add_error_handler(asyncio.TimeoutError, timeout_error_handler) # type: ignore[arg-type]
legacy_urls = api.config.get_bool('SERVE_LEGACY_URLS')
+ formatter = load_format_dispatcher('v1', project_dir)
for name, func in api_impl.ROUTES:
- endpoint = EndpointWrapper(name, func, api)
+ endpoint = EndpointWrapper(name, func, api, formatter)
app.add_route(f"/{name}", endpoint)
if legacy_urls:
app.add_route(f"/{name}.php", endpoint)