]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/server/starlette/server.py
add support for starlette framework
[nominatim.git] / nominatim / server / starlette / server.py
1 # SPDX-License-Identifier: GPL-2.0-only
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2022 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Server implementation using the starlette webserver framework.
9 """
10 from pathlib import Path
11
12 from starlette.applications import Starlette
13 from starlette.routing import Route
14 from starlette.exceptions import HTTPException
15 from starlette.responses import Response
16
17 from nominatim.api import NominatimAPIAsync
18 from nominatim.apicmd.status import StatusResult
19 import nominatim.result_formatter.v1 as formatting
20
21 CONTENT_TYPE = {
22   'text': 'text/plain; charset=utf-8',
23   'xml': 'text/xml; charset=utf-8'
24 }
25
26 FORMATTERS = {
27     StatusResult: formatting.create(StatusResult)
28 }
29
30
31 def parse_format(request, rtype, default):
32     fmt = request.query_params.get('format', default=default)
33     fmtter = FORMATTERS[rtype]
34
35     if not fmtter.supports_format(fmt):
36         raise HTTPException(400, detail="Parameter 'format' must be one of: " +
37                                         ', '.join(fmtter.list_formats()))
38
39     request.state.format = fmt
40     request.state.formatter = fmtter
41
42
43 def format_response(request, result):
44     fmt = request.state.format
45     return Response(request.state.formatter.format(result, fmt),
46                     media_type=CONTENT_TYPE.get(fmt, 'application/json'))
47
48
49 async def on_status(request):
50     parse_format(request, StatusResult, 'text')
51     result = await request.app.state.API.status()
52     return format_response(request, result)
53
54
55 V1_ROUTES = [
56     Route('/status', endpoint=on_status)
57 ]
58
59 def get_application(project_dir: Path) -> Starlette:
60     app = Starlette(debug=True, routes=V1_ROUTES)
61
62     app.state.API = NominatimAPIAsync(project_dir)
63
64     return app