add support for falcon as server framework

This commit is contained in:
Sarah Hoffmann 2022-12-02 17:28:46 +01:00
parent 23dabad0b0
commit 8aa01c9c8e
3 changed files with 75 additions and 8 deletions

View File

@ -221,11 +221,7 @@ class AdminServe:
def run(self, args: NominatimArgs) -> int:
if args.engine == 'php':
run_php_server(args.server, args.project_dir / 'website')
elif args.engine == 'sanic':
import nominatim.server.sanic.server
app = nominatim.server.sanic.server.get_application(args.project_dir)
else:
server_info = args.server.split(':', 1)
host = server_info[0]
if len(server_info) > 1:
@ -234,9 +230,18 @@ class AdminServe:
port = int(server_info[1])
else:
port = 8088
app.run(host=host, port=port, debug=True)
elif args.engine == 'falcon':
raise NotImplementedError('Support for falcon not yet available.')
if args.engine == 'sanic':
import nominatim.server.sanic.server
app = nominatim.server.sanic.server.get_application(args.project_dir)
app.run(host=host, port=port, debug=True)
elif args.engine == 'falcon':
import uvicorn
import nominatim.server.falcon.server
app = nominatim.server.falcon.server.get_application(args.project_dir)
uvicorn.run(app, host=host, port=port)
return 0

View File

View File

@ -0,0 +1,62 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# This file is part of Nominatim. (https://nominatim.org)
#
# Copyright (C) 2022 by the Nominatim developer community.
# For a full list of authors see the git log.
"""
Server implementation using the falcon webserver framework.
"""
from pathlib import Path
import falcon.asgi
from nominatim.api import NominatimAPIAsync
from nominatim.apicmd.status import StatusResult
import nominatim.result_formatter.v1 as formatting
CONTENT_TYPE = {
'text': falcon.MEDIA_TEXT,
'xml': falcon.MEDIA_XML
}
class NominatimV1:
def __init__(self, project_dir: Path):
self.api = NominatimAPIAsync(project_dir)
self.formatters = {}
for rtype in (StatusResult, ):
self.formatters[rtype] = formatting.create(rtype)
def parse_format(self, req, rtype, default):
req.context.format = req.get_param('format', default=default)
req.context.formatter = self.formatters[rtype]
if not req.context.formatter.supports_format(req.context.format):
raise falcon.HTTPBadRequest(
description="Parameter 'format' must be one of: " +
', '.join(req.context.formatter.list_formats()))
def format_response(self, req, resp, result):
resp.text = req.context.formatter.format(result, req.context.format)
resp.content_type = CONTENT_TYPE.get(req.context.format, falcon.MEDIA_JSON)
async def on_get_status(self, req, resp):
self.parse_format(req, StatusResult, 'text')
result = await self.api.status()
self.format_response(req, resp, result)
def get_application(project_dir: Path) -> falcon.asgi.App:
app = falcon.asgi.App()
api = NominatimV1(project_dir)
app.add_route('/status', api, suffix='status')
return app