mirror of
https://github.com/osm-search/Nominatim.git
synced 2024-12-25 14:02:12 +03:00
extend BDD API tests to query via Python frameworks
A new config option ENGINE allows to choose between php and any of the supported Python engines.
This commit is contained in:
parent
d7bc846c3c
commit
7219ee6532
@ -7,7 +7,7 @@
|
||||
"""
|
||||
Server implementation using the falcon webserver framework.
|
||||
"""
|
||||
from typing import Type, Any
|
||||
from typing import Type, Any, Optional, Mapping
|
||||
from pathlib import Path
|
||||
|
||||
import falcon
|
||||
@ -26,8 +26,8 @@ class NominatimV1:
|
||||
""" Implementation of V1 version of the Nominatim API.
|
||||
"""
|
||||
|
||||
def __init__(self, project_dir: Path) -> None:
|
||||
self.api = NominatimAPIAsync(project_dir)
|
||||
def __init__(self, project_dir: Path, environ: Optional[Mapping[str, str]]) -> None:
|
||||
self.api = NominatimAPIAsync(project_dir, environ)
|
||||
self.formatters = {}
|
||||
|
||||
for rtype in (StatusResult, ):
|
||||
@ -67,12 +67,13 @@ class NominatimV1:
|
||||
self.format_response(req, resp, result)
|
||||
|
||||
|
||||
def get_application(project_dir: Path) -> falcon.asgi.App:
|
||||
def get_application(project_dir: Path,
|
||||
environ: Optional[Mapping[str, str]] = None) -> falcon.asgi.App:
|
||||
""" Create a Nominatim falcon ASGI application.
|
||||
"""
|
||||
app = falcon.asgi.App()
|
||||
|
||||
api = NominatimV1(project_dir)
|
||||
api = NominatimV1(project_dir, environ)
|
||||
|
||||
app.add_route('/status', api, suffix='status')
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
"""
|
||||
Server implementation using the sanic webserver framework.
|
||||
"""
|
||||
from typing import Any, Optional
|
||||
from typing import Any, Optional, Mapping
|
||||
from pathlib import Path
|
||||
|
||||
import sanic
|
||||
@ -64,12 +64,13 @@ async def status(request: sanic.Request) -> sanic.HTTPResponse:
|
||||
return api_response(request,await request.app.ctx.api.status())
|
||||
|
||||
|
||||
def get_application(project_dir: Path) -> sanic.Sanic:
|
||||
def get_application(project_dir: Path,
|
||||
environ: Optional[Mapping[str, str]] = None) -> sanic.Sanic:
|
||||
""" Create a Nominatim sanic ASGI application.
|
||||
"""
|
||||
app = sanic.Sanic("NominatimInstance")
|
||||
|
||||
app.ctx.api = NominatimAPIAsync(project_dir)
|
||||
app.ctx.api = NominatimAPIAsync(project_dir, environ)
|
||||
app.ctx.formatters = {}
|
||||
for rtype in (StatusResult, ):
|
||||
app.ctx.formatters[rtype] = formatting.create(rtype)
|
||||
|
@ -7,7 +7,7 @@
|
||||
"""
|
||||
Server implementation using the starlette webserver framework.
|
||||
"""
|
||||
from typing import Any, Type
|
||||
from typing import Any, Type, Optional, Mapping
|
||||
from pathlib import Path
|
||||
|
||||
from starlette.applications import Starlette
|
||||
@ -67,11 +67,12 @@ V1_ROUTES = [
|
||||
Route('/status', endpoint=on_status)
|
||||
]
|
||||
|
||||
def get_application(project_dir: Path) -> Starlette:
|
||||
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)
|
||||
app.state.API = NominatimAPIAsync(project_dir, environ)
|
||||
|
||||
return app
|
||||
|
@ -28,6 +28,7 @@ userconfig = {
|
||||
'SERVER_MODULE_PATH' : None,
|
||||
'TOKENIZER' : None, # Test with a custom tokenizer
|
||||
'STYLE' : 'extratags',
|
||||
'API_ENGINE': 'php',
|
||||
'PHPCOV' : False, # set to output directory to enable code coverage
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,13 @@
|
||||
# Copyright (C) 2022 by the Nominatim developer community.
|
||||
# For a full list of authors see the git log.
|
||||
from pathlib import Path
|
||||
import importlib
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from asgi_lifespan import LifespanManager
|
||||
import httpx
|
||||
|
||||
import psycopg2
|
||||
import psycopg2.extras
|
||||
|
||||
@ -49,6 +53,12 @@ class NominatimEnvironment:
|
||||
self.api_db_done = False
|
||||
self.website_dir = None
|
||||
|
||||
self.api_engine = None
|
||||
if config['API_ENGINE'] != 'php':
|
||||
if not hasattr(self, f"create_api_request_func_{config['API_ENGINE']}"):
|
||||
raise RuntimeError(f"Unknown API engine '{config['API_ENGINE']}'")
|
||||
self.api_engine = getattr(self, f"create_api_request_func_{config['API_ENGINE']}")()
|
||||
|
||||
def connect_database(self, dbname):
|
||||
""" Return a connection to the database with the given name.
|
||||
Uses configured host, user and port.
|
||||
@ -323,3 +333,49 @@ class NominatimEnvironment:
|
||||
WHERE class='place' and type='houses'
|
||||
and osm_type='W'
|
||||
and ST_GeometryType(geometry) = 'ST_LineString'""")
|
||||
|
||||
|
||||
def create_api_request_func_starlette(self):
|
||||
import nominatim.server.starlette.server
|
||||
|
||||
async def _request(endpoint, params, project_dir, environ):
|
||||
app = nominatim.server.starlette.server.get_application(project_dir, environ)
|
||||
|
||||
async with LifespanManager(app):
|
||||
async with httpx.AsyncClient(app=app, base_url="http://nominatim.test") as client:
|
||||
response = await client.get(f"/{endpoint}", params=params)
|
||||
|
||||
return response.text, response.status_code
|
||||
|
||||
return _request
|
||||
|
||||
|
||||
def create_api_request_func_sanic(self):
|
||||
import nominatim.server.sanic.server
|
||||
|
||||
async def _request(endpoint, params, project_dir, environ):
|
||||
app = nominatim.server.sanic.server.get_application(project_dir, environ)
|
||||
|
||||
_, response = await app.asgi_client.get(f"/{endpoint}", params=params)
|
||||
|
||||
return response.text, response.status_code
|
||||
|
||||
return _request
|
||||
|
||||
|
||||
def create_api_request_func_falcon(self):
|
||||
import nominatim.server.falcon.server
|
||||
import falcon.testing
|
||||
|
||||
async def _request(endpoint, params, project_dir, environ):
|
||||
app = nominatim.server.falcon.server.get_application(project_dir, environ)
|
||||
|
||||
async with falcon.testing.ASGIConductor(app) as conductor:
|
||||
response = await conductor.get(f"/{endpoint}", params=params)
|
||||
|
||||
return response.text, response.status_code
|
||||
|
||||
return _request
|
||||
|
||||
|
||||
|
||||
|
@ -9,10 +9,12 @@
|
||||
Queries may either be run directly via PHP using the query script
|
||||
or via the HTTP interface using php-cgi.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
import asyncio
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from utils import run_script
|
||||
@ -72,6 +74,16 @@ def send_api_query(endpoint, params, fmt, context):
|
||||
for h in context.table.headings:
|
||||
params[h] = context.table[0][h]
|
||||
|
||||
if context.nominatim.api_engine is None:
|
||||
return send_api_query_php(endpoint, params, context)
|
||||
|
||||
return asyncio.run(context.nominatim.api_engine(endpoint, params,
|
||||
Path(context.nominatim.website_dir.name),
|
||||
context.nominatim.test_env))
|
||||
|
||||
|
||||
|
||||
def send_api_query_php(endpoint, params, context):
|
||||
env = dict(BASE_SERVER_ENV)
|
||||
env['QUERY_STRING'] = urlencode(params)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user