]> git.openstreetmap.org Git - nominatim.git/commitdiff
add support for falcon as server framework
authorSarah Hoffmann <lonvia@denofr.de>
Fri, 2 Dec 2022 16:28:46 +0000 (17:28 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Tue, 3 Jan 2023 09:03:00 +0000 (10:03 +0100)
nominatim/cli.py
nominatim/server/falcon/__init__.py [new file with mode: 0644]
nominatim/server/falcon/server.py [new file with mode: 0644]

index c134ca1808c2a2fe7267fc26947c54931bb23ab7..34abb617efe3346aa156b3055ab36da045b7b594 100644 (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
 
diff --git a/nominatim/server/falcon/__init__.py b/nominatim/server/falcon/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/nominatim/server/falcon/server.py b/nominatim/server/falcon/server.py
new file mode 100644 (file)
index 0000000..a1ae9c6
--- /dev/null
@@ -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