mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-26 11:08:13 +00:00
Code is now organized by api version. So formatting has moved to the api.v1 module. Instead of holding a separate ResultFormatter object per result format, simply move the functions to the formater collector and hand in the requested format as a parameter. Thus reorganized, the api.v1 module can export three simple functions for result formatting which in turn makes the code that uses the formatters much simpler.
75 lines
2.3 KiB
Python
75 lines
2.3 KiB
Python
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
# This file is part of Nominatim. (https://nominatim.org)
|
|
#
|
|
# Copyright (C) 2023 by the Nominatim developer community.
|
|
# For a full list of authors see the git log.
|
|
"""
|
|
Server implementation using the starlette webserver framework.
|
|
"""
|
|
from typing import Any, Type, Optional, Mapping
|
|
from pathlib import Path
|
|
|
|
from starlette.applications import Starlette
|
|
from starlette.routing import Route
|
|
from starlette.exceptions import HTTPException
|
|
from starlette.responses import Response
|
|
from starlette.requests import Request
|
|
|
|
from nominatim.api import NominatimAPIAsync, StatusResult
|
|
import nominatim.api.v1 as api_impl
|
|
|
|
CONTENT_TYPE = {
|
|
'text': 'text/plain; charset=utf-8',
|
|
'xml': 'text/xml; charset=utf-8'
|
|
}
|
|
|
|
def parse_format(request: Request, rtype: Type[Any], default: str) -> None:
|
|
""" Get and check the 'format' parameter and prepare the formatter.
|
|
`rtype` describes the expected return type and `default` the
|
|
format value to assume when no parameter is present.
|
|
"""
|
|
fmt = request.query_params.get('format', default=default)
|
|
|
|
if not api_impl.supports_format(rtype, fmt):
|
|
raise HTTPException(400, detail="Parameter 'format' must be one of: " +
|
|
', '.join(api_impl.list_formats(rtype)))
|
|
|
|
request.state.format = fmt
|
|
|
|
|
|
def format_response(request: Request, result: Any) -> Response:
|
|
""" Render response into a string according.
|
|
"""
|
|
fmt = request.state.format
|
|
return Response(api_impl.format_result(result, fmt),
|
|
media_type=CONTENT_TYPE.get(fmt, 'application/json'))
|
|
|
|
|
|
async def on_status(request: Request) -> Response:
|
|
""" Implementation of status endpoint.
|
|
"""
|
|
parse_format(request, StatusResult, 'text')
|
|
result = await request.app.state.API.status()
|
|
response = format_response(request, result)
|
|
|
|
if request.state.format == 'text' and result.status:
|
|
response.status_code = 500
|
|
|
|
return response
|
|
|
|
|
|
V1_ROUTES = [
|
|
Route('/status', endpoint=on_status)
|
|
]
|
|
|
|
def get_application(project_dir: Path,
|
|
environ: Optional[Mapping[str, str]] = None) -> Starlette:
|
|
""" Create a Nominatim falcon ASGI application.
|
|
"""
|
|
app = Starlette(debug=True, routes=V1_ROUTES)
|
|
|
|
app.state.API = NominatimAPIAsync(project_dir, environ)
|
|
|
|
return app
|