Skip to content

Commit

Permalink
Merge pull request #3339 from lonvia/python-frontend-as-default
Browse files Browse the repository at this point in the history
Switch to Python frontend as the default
  • Loading branch information
lonvia authored Feb 20, 2024
2 parents 19360a9 + cf49a07 commit 5afd96d
Show file tree
Hide file tree
Showing 17 changed files with 322 additions and 257 deletions.
66 changes: 29 additions & 37 deletions .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
with:
submodules: true

- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
data/country_osm_grid.sql.gz
Expand All @@ -27,7 +27,7 @@ jobs:
mv nominatim-src.tar.bz2 Nominatim
- name: 'Upload Artifact'
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: full-source
path: nominatim-src.tar.bz2
Expand All @@ -43,40 +43,28 @@ jobs:
ubuntu: 20
postgresql: '9.6'
postgis: '2.5'
php: '7.3'
lua: '5.1'
- flavour: ubuntu-20
ubuntu: 20
postgresql: 13
postgis: 3
php: '7.4'
lua: '5.3'
- flavour: ubuntu-22
ubuntu: 22
postgresql: 15
postgis: 3
php: '8.1'
lua: '5.3'

runs-on: ubuntu-${{ matrix.ubuntu }}.04

steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: full-source

- name: Unpack Nominatim
run: tar xf nominatim-src.tar.bz2

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: phpunit:9, phpcs, composer
ini-values: opcache.jit=disable
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v4
with:
python-version: 3.7
Expand Down Expand Up @@ -119,20 +107,11 @@ jobs:
run: pip3 install -U pylint
if: matrix.flavour != 'oldstuff'

- name: PHP linting
run: phpcs --report-width=120 .
working-directory: Nominatim
if: matrix.flavour != 'oldstuff'

- name: Python linting
run: python3 -m pylint nominatim
working-directory: Nominatim
if: matrix.flavour != 'oldstuff'

- name: PHP unit tests
run: phpunit ./
working-directory: Nominatim/test/php

- name: Python unit tests
run: python3 -m pytest test/python
working-directory: Nominatim
Expand All @@ -156,7 +135,7 @@ jobs:
runs-on: ubuntu-20.04

steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: full-source

Expand Down Expand Up @@ -185,16 +164,16 @@ jobs:

- name: BDD tests (legacy tokenizer)
run: |
python3 -m behave -DREMOVE_TEMPLATE=1 -DBUILDDIR=$GITHUB_WORKSPACE/build -DTOKENIZER=legacy --format=progress3
python3 -m behave -DREMOVE_TEMPLATE=1 -DBUILDDIR=$GITHUB_WORKSPACE/build -DAPI_ENGINE=php -DTOKENIZER=legacy --format=progress3
working-directory: Nominatim/test/bdd


python-api-test:
php-test:
needs: create-archive
runs-on: ubuntu-22.04

steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: full-source

Expand All @@ -206,19 +185,33 @@ jobs:
postgresql-version: 15
postgis-version: 3

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
tools: phpunit:9, phpcs, composer
ini-values: opcache.jit=disable
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: PHP linting
run: phpcs --report-width=120 .
working-directory: Nominatim

- name: PHP unit tests
run: phpunit ./
working-directory: Nominatim/test/php

- uses: ./Nominatim/.github/actions/build-nominatim
with:
flavour: 'ubuntu-22'

- name: Install test prerequsites
run: sudo apt-get install -y -qq python3-behave

- name: Install Python webservers
run: pip3 install starlette asgi_lifespan httpx

- name: BDD tests (starlette)
- name: BDD tests (php)
run: |
python3 -m behave -DREMOVE_TEMPLATE=1 -DBUILDDIR=$GITHUB_WORKSPACE/build -DAPI_ENGINE=starlette --format=progress3
python3 -m behave -DREMOVE_TEMPLATE=1 -DBUILDDIR=$GITHUB_WORKSPACE/build -DAPI_ENGINE=php --format=progress3
working-directory: Nominatim/test/bdd


Expand Down Expand Up @@ -268,7 +261,7 @@ jobs:
OS: ${{ matrix.name }}
INSTALL_MODE: ${{ matrix.install_mode }}

- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: full-source
path: /home/nominatim
Expand Down Expand Up @@ -355,7 +348,7 @@ jobs:
needs: create-archive

steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: full-source

Expand Down Expand Up @@ -392,5 +385,4 @@ jobs:
NOMINATIM_DATABASE_DSN="pgsql:host=127.0.0.1;dbname=nominatim;user=osm-import;password=osm-import" nominatim import --continue import-from-file --osm-file test.pbf
- name: Check full import
run: |
nominatim admin --check-database
run: nominatim admin --check-database
13 changes: 9 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,14 @@ endif()

# Setting PHP binary variable as to command line (prevailing) or auto detect

if (BUILD_API OR BUILD_IMPORTER)
if (BUILD_API)
if (NOT PHP_BIN)
find_program (PHP_BIN php)
endif()
# sanity check if PHP binary exists
if (NOT EXISTS ${PHP_BIN})
message(FATAL_ERROR "PHP binary not found. Install php or provide location with -DPHP_BIN=/path/php ")
message(WARNING "PHP binary not found. Only Python frontend can be used.")
set(PHP_BIN "")
else()
message (STATUS "Using PHP binary " ${PHP_BIN})
endif()
Expand Down Expand Up @@ -226,7 +227,11 @@ if (BUILD_IMPORTER)
PATTERN "paths.py" EXCLUDE
PATTERN __pycache__ EXCLUDE)

configure_file(${PROJECT_SOURCE_DIR}/cmake/paths-py.tmpl paths-py.installed)
if (EXISTS ${PHP_BIN})
configure_file(${PROJECT_SOURCE_DIR}/cmake/paths-py.tmpl paths-py.installed)
else()
configure_file(${PROJECT_SOURCE_DIR}/cmake/paths-py-no-php.tmpl paths-py.installed)
endif()
install(FILES ${PROJECT_BINARY_DIR}/paths-py.installed
DESTINATION ${NOMINATIM_LIBDIR}/lib-python/nominatim
RENAME paths.py)
Expand Down Expand Up @@ -254,7 +259,7 @@ if (BUILD_MODULE)
DESTINATION ${NOMINATIM_LIBDIR}/module)
endif()

if (BUILD_API)
if (BUILD_API AND EXISTS ${PHP_BIN})
install(DIRECTORY lib-php DESTINATION ${NOMINATIM_LIBDIR})
endif()

Expand Down
2 changes: 1 addition & 1 deletion Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Vagrant.configure("2") do |config|
lv.memory = 2048
lv.nested = true
if ENV['CHECKOUT'] != 'y' then
override.vm.synced_folder ".", "/home/vagrant/Nominatim", type: 'nfs'
override.vm.synced_folder ".", "/home/vagrant/Nominatim", type: 'nfs', nfs_udp: false
end
end

Expand Down
15 changes: 15 additions & 0 deletions cmake/paths-py-no-php.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 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.
"""
Path settings for extra data used by Nominatim (installed version).
"""
from pathlib import Path

PHPLIB_DIR = None
SQLLIB_DIR = (Path('@NOMINATIM_LIBDIR@') / 'lib-sql').resolve()
DATA_DIR = Path('@NOMINATIM_DATADIR@').resolve()
CONFIG_DIR = Path('@NOMINATIM_CONFIGDIR@').resolve()
37 changes: 19 additions & 18 deletions docs/admin/Import.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,41 +268,41 @@ nominatim reverse --lat 51 --lon 45
```

If you want to run Nominatim as a service, you need to make a choice between
running the traditional PHP frontend or the new experimental Python frontend.
running the modern Python frontend and the legacy PHP frontend.
Make sure you have installed the right packages as per
[Installation](Installation.md#software).

#### Testing the PHP frontend
#### Testing the Python frontend

You can run a small test server with the PHP frontend like this:
To run the test server against the Python frontend, you must choose a
web framework to use, either starlette or falcon. Make sure the appropriate
packages are installed. Then run

```sh
``` sh
nominatim serve
```

or, if you prefer to use Starlette instead of Falcon as webserver,

``` sh
nominatim serve --engine starlette
```

Go to `http://localhost:8088/status.php` and you should see the message `OK`.
You can also run a search query, e.g. `http://localhost:8088/search.php?q=Berlin`
or, for reverse-only installations a reverse query,
e.g. `http://localhost:8088/reverse.php?lat=27.1750090510034&lon=78.04209025`.

Do not use this test server in production.
To run Nominatim via webservers like Apache or nginx, please continue reading
[Deploy the PHP frontend](Deployment-PHP.md).

#### Testing the Python frontend

To run the test server against the Python frontend, you must choose a
web framework to use, either starlette or falcon. Make sure the appropriate
packages are installed. Then run
[Deploy the Python frontend](Deployment-Python.md).

``` sh
nominatim serve --engine falcon
```
#### Testing the PHP frontend

or
You can run a small test server with the PHP frontend like this:

``` sh
nominatim serve --engine starlette
```sh
nominatim serve --engine php
```

Go to `http://localhost:8088/status.php` and you should see the message `OK`.
Expand All @@ -312,7 +312,8 @@ e.g. `http://localhost:8088/reverse.php?lat=27.1750090510034&lon=78.04209025`.

Do not use this test server in production.
To run Nominatim via webservers like Apache or nginx, please continue reading
[Deploy the Python frontend](Deployment-Python.md).
[Deploy the PHP frontend](Deployment-PHP.md).



## Enabling search by category phrases
Expand Down
15 changes: 8 additions & 7 deletions docs/admin/Installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,24 @@ For running Nominatim:
* [PyYaml](https://pyyaml.org/) (5.1+)
* [datrie](https://github.com/pytries/datrie)

When running the PHP frontend:

* [PHP](https://php.net) (7.3+)
* PHP-pgsql
* PHP-intl (bundled with PHP)

For running continuous updates:

* [pyosmium](https://osmcode.org/pyosmium/)

For running the experimental Python frontend:
For running the Python frontend:

* one of the following web frameworks:
* [falcon](https://falconframework.org/) (3.0+)
* [starlette](https://www.starlette.io/)
* [uvicorn](https://www.uvicorn.org/)

For running the legacy PHP frontend:

* [PHP](https://php.net) (7.3+)
* PHP-pgsql
* PHP-intl (bundled with PHP)


For dependencies for running tests and building documentation, see
the [Development section](../develop/Development-Environment.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ nav:
- 'Basic Installation': 'admin/Installation.md'
- 'Import' : 'admin/Import.md'
- 'Update' : 'admin/Update.md'
- 'Deploy (PHP frontend)' : 'admin/Deployment-PHP.md'
- 'Deploy (Python frontend)' : 'admin/Deployment-Python.md'
- 'Deploy (PHP frontend)' : 'admin/Deployment-PHP.md'
- 'Nominatim UI' : 'admin/Setup-Nominatim-UI.md'
- 'Advanced Installations' : 'admin/Advanced-Installations.md'
- 'Maintenance' : 'admin/Maintenance.md'
Expand Down
5 changes: 3 additions & 2 deletions nominatim/api/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import textwrap
import io
import re
import html

import sqlalchemy as sa
from sqlalchemy.ext.asyncio import AsyncConnection
Expand Down Expand Up @@ -227,15 +228,15 @@ def sql(self, conn: AsyncConnection, statement: 'sa.Executable',
HtmlFormatter(nowrap=True, lineseparator='<br />'))
self._write(f'<div class="highlight"><code class="lang-sql">{sqlstr}</code></div>')
else:
self._write(f'<code class="lang-sql">{sqlstr}</code>')
self._write(f'<code class="lang-sql">{html.escape(sqlstr)}</code>')


def _python_var(self, var: Any) -> str:
if CODE_HIGHLIGHT:
fmt = highlight(str(var), PythonLexer(), HtmlFormatter(nowrap=True))
return f'<div class="highlight"><code class="lang-python">{fmt}</code></div>'

return f'<code class="lang-python">{str(var)}</code>'
return f'<code class="lang-python">{html.escape(str(var))}</code>'


def _write(self, text: str) -> None:
Expand Down
6 changes: 4 additions & 2 deletions nominatim/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,15 @@ def add_args(self, parser: argparse.ArgumentParser) -> None:
group = parser.add_argument_group('Server arguments')
group.add_argument('--server', default='127.0.0.1:8088',
help='The address the server will listen to.')
group.add_argument('--engine', default='php',
group.add_argument('--engine', default='falcon',
choices=('php', 'falcon', 'starlette'),
help='Webserver framework to run. (default: php)')
help='Webserver framework to run. (default: falcon)')


def run(self, args: NominatimArgs) -> int:
if args.engine == 'php':
if args.config.lib_dir.php is None:
raise UsageError("PHP frontend not configured.")
run_php_server(args.server, args.project_dir / 'website')
else:
import uvicorn # pylint: disable=import-outside-toplevel
Expand Down
Loading

0 comments on commit 5afd96d

Please sign in to comment.