Skip to content

Commit ce4dba0

Browse files
authored
Merge pull request #11607 from gem/post-inst_to-docutils19
Downgrade docutils dependency to 0.19 version.
2 parents 5f35b0a + 45b53b8 commit ce4dba0

5 files changed

Lines changed: 209 additions & 62 deletions

File tree

.github/workflows/webui_rh_test.yml

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,32 @@ jobs:
6666
eval '$mypython -m pip install -e . '
6767
## Standalone apps
6868
echo "Downloading standalone apps"
69-
for app in oq-platform-standalone oq-platform-ipt oq-platform-taxonomy; do
70-
# do not fail on exit code 2 if the branch
71-
# does not exist in the app repository
72-
set +e
73-
git ls-remote --exit-code --heads https://github.com/gem/${app}.git $BRANCH >/dev/null 2>&1
74-
EXIT_CODE=$?
75-
# set again to fail on exit code not 0
76-
set -e
77-
if [[ $EXIT_CODE == '0' ]]; then
78-
echo "Git branch '$BRANCH' exists in the remote repository"
79-
TOOLS_BRANCH=$BRANCH
80-
elif [[ $EXIT_CODE == '2' ]]; then
81-
echo "Git branch '$BRANCH' does not exist in the remote repository"
82-
TOOLS_BRANCH=master
83-
fi
84-
echo "We need to use the branch $TOOLS_BRANCH for the standalone apps"
85-
git clone -b ${TOOLS_BRANCH} --depth=1 https://github.com/gem/${app}.git
86-
eval '$mypython -m pip install -e ./${app}'
69+
for app in oq-platform-standalone django-gem-taxonomy oq-platform-ipt oq-platform-taxonomy; do
70+
for branch in "$BRANCH" "master" "main"; do
71+
TOOLS_BRANCH="$branch"
72+
# do not fail on exit code 2 if the branch
73+
# does not exist in the app repository
74+
set +e
75+
git ls-remote --exit-code --heads https://github.com/gem/${app}.git $TOOLS_BRANCH >/dev/null 2>&1
76+
EXIT_CODE=$?
77+
# set again to fail on exit code not 0
78+
set -e
79+
if [[ $EXIT_CODE -eq 0 ]]; then
80+
echo "Git branch '$BRANCH' exists in the remote repository"
81+
break
82+
fi
83+
done
84+
if [[ $EXIT_CODE -ne 0 ]]; then
85+
break
86+
fi
87+
echo "We need to use the branch $TOOLS_BRANCH for the standalone apps"
88+
git clone -b ${TOOLS_BRANCH} --depth=1 https://github.com/gem/${app}.git
89+
eval '$mypython -m pip install -e ./${app}'
8790
done
91+
if [ $EXIT_CODE -ne 0 ]; then
92+
echo "No '$branch', nor 'master' or 'main' branch found for '$app' django app; failed"
93+
exit 1
94+
fi
8895
deactivate
8996
- name: Actualize 'default' templates for email notifications
9097
run: |

install.py

Lines changed: 100 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,9 @@ class devel(user):
219219
"win32": ("win64",),
220220
}
221221
GITBRANCH = "https://github.com/gem/oq-engine/archive/%s.zip"
222-
URL_STANDALONE = "https://wheelhouse.openquake.org/py/standalone/latest/"
222+
# FIXME just for devel test
223+
# URL_STANDALONE = "https://wheelhouse.openquake.org/py/standalone/latest/"
224+
URL_STANDALONE = "https://wheelhouse.openquake.org/py/standalone/post-inst/"
223225

224226

225227
def ensure(pip=None, pyvenv=None):
@@ -271,37 +273,75 @@ def get_requirements_branch(version, inst, from_fork):
271273
return version
272274

273275

274-
def install_standalone(venv):
276+
def install_or_postinstall_standalone(venv, is_install=True):
275277
"""
276-
Install the standalone Django applications if possible
278+
Install the standalone Django applications if possible or
279+
run '<app>_postinstall' command if it exists
277280
"""
278281
errors = []
279-
print("The standalone applications are not installed yet")
282+
if is_install:
283+
print("The standalone applications are not installed yet")
284+
else:
285+
print("Run '<app>_postinstall' command for each standalone\n"
286+
" Django applications, if it exists")
280287
if sys.platform == "win32":
281288
if os.path.exists("python\\python._pth.old"):
282289
pycmd = inst.VENV + "\\python.exe"
283290
else:
284291
pycmd = inst.VENV + "\\Scripts\\python.exe"
285292
else:
286293
pycmd = inst.VENV + "/bin/python3"
287-
for app in [
288-
"oq-platform-standalone",
289-
"oq-platform-ipt",
290-
"oq-platform-taxonomy",
291-
]:
292-
try:
293-
print("Applications " + app + " are not installed yet \n")
294294

295-
subprocess.check_call(
296-
[pycmd, "-m", "pip", "install", "--find-links", URL_STANDALONE,
297-
app]
298-
)
299-
except Exception as exc:
300-
# for instance is somebody removed a wheel from the wheelhouse
301-
errors.append("%s: could not install %s" % (exc, app))
295+
STANDALONE_APP_INFO = [
296+
{"pkg": "oq-platform-standalone", "name": None},
297+
{"pkg": "oq-platform-ipt", "name": "openquakeplatform_ipt"},
298+
{"pkg": "oq-platform-taxonomy", "name": "openquakeplatform_taxonomy"},
299+
{"pkg": "django-gem-taxonomy", "name": "django_gem_taxonomy"},
300+
]
301+
302+
if is_install:
303+
for app in STANDALONE_APP_INFO:
304+
try:
305+
print("Applications " + app['pkg'] + " are not installed yet \n")
306+
307+
subprocess.check_call(
308+
[pycmd, "-m", "pip", "install", "--find-links", URL_STANDALONE,
309+
app['pkg']]
310+
)
311+
except Exception as exc:
312+
# for instance is somebody removed a wheel from the wheelhouse
313+
errors.append("%s: could not install %s" % (exc, app['pkg']))
314+
else:
315+
for app in STANDALONE_APP_INFO:
316+
if not app['name']:
317+
continue
318+
319+
try:
320+
if sys.platform == "win32":
321+
django_admin = ['Scripts', 'django-admin.exe']
322+
else:
323+
django_admin = ["bin", "django-admin"]
324+
325+
django_env = os.environ.copy()
326+
django_env["DJANGO_SETTINGS_MODULE"] = "openquake.server.settings"
327+
328+
subprocess.check_call(
329+
[os.path.join(inst.VENV, *django_admin),
330+
"openquake_engine_postinstall", app['name']],
331+
env=django_env)
332+
except Exception as exc:
333+
# for instance is somebody removed a wheel from the wheelhouse
334+
errors.append("%s: error during %s postinstall command execution" % (exc, app['name']))
335+
302336
return errors
303337

304338

339+
def install_standalone(venv):
340+
return install_or_postinstall_standalone(venv, is_install=True)
341+
342+
def postinstall_standalone(venv):
343+
return install_or_postinstall_standalone(venv, is_install=False)
344+
305345
def before_checks(inst, args, usage):
306346
"""
307347
Checks to perform before the installation
@@ -311,6 +351,10 @@ def before_checks(inst, args, usage):
311351
if args.dbport:
312352
inst.DBPORT = int(args.dbport)
313353

354+
if args.novenv:
355+
inst.VENV = os.path.join(os.getenv('LocalAppData'), 'Programs',
356+
'OpenQuake Engine', 'python3')
357+
314358
# check platform
315359
if (inst is server and sys.platform != "linux") or (
316360
inst is devel_server and sys.platform != "linux"
@@ -427,7 +471,7 @@ def normalize_version(version):
427471
return f"=={version}"
428472

429473

430-
def install(inst, version, from_fork):
474+
def install(inst, version, from_fork, novenv, noupgrade):
431475
"""
432476
Install the engine in one of the three possible modes
433477
"""
@@ -447,34 +491,38 @@ def install(inst, version, from_fork):
447491
if inst is server or inst is devel_server:
448492
subprocess.check_call(["chown", "openquake", inst.OQDATA])
449493

450-
# recreate the openquake venv
451-
ensure(pyvenv=inst.VENV)
452-
print("Created %s" % inst.VENV)
494+
if not novenv:
495+
# recreate the openquake venv
496+
ensure(pyvenv=inst.VENV)
497+
print("Created %s" % inst.VENV)
453498

454-
if sys.platform == "win32":
455-
if os.path.exists("python\\python._pth.old"):
456-
pycmd = inst.VENV + "\\python.exe"
499+
if sys.platform == "win32":
500+
if os.path.exists("python\\python._pth.old"):
501+
pycmd = inst.VENV + "\\python.exe"
502+
else:
503+
pycmd = inst.VENV + "\\Scripts\\python.exe"
457504
else:
458-
pycmd = inst.VENV + "\\Scripts\\python.exe"
505+
pycmd = inst.VENV + "/bin/python3"
459506
else:
460-
pycmd = inst.VENV + "/bin/python3"
507+
pycmd = os.path.join(inst.VENV, 'python.exe')
461508

462509
# upgrade pip and before check that it is installed in venv
463510
if sys.platform != "win32":
464511
ensure(pip=pycmd)
465-
subprocess.check_call(
466-
[pycmd, "-m", "pip", "install", "--upgrade", "pip", "wheel"]
467-
)
512+
subprocess.check_call([pycmd, "-m", "pip", "install"] + ([
513+
] if noupgrade else ["--upgrade"]) + [
514+
"pip", "wheel"])
468515
else:
469516
if os.path.exists("python\\python._pth.old"):
470-
subprocess.check_call(
471-
[pycmd, "-m", "pip", "install", "--upgrade", "pip", "wheel",
472-
"urllib3"])
517+
subprocess.check_call([pycmd, "-m", "pip", "install"] + ([
518+
] if noupgrade else ["--upgrade"]) + [
519+
"pip", "wheel", "urllib3"])
473520
else:
474-
subprocess.check_call([pycmd, "-m", "ensurepip", "--upgrade"])
475-
subprocess.check_call(
476-
[pycmd, "-m", "pip", "install", "--upgrade", "pip", "wheel",
477-
"urllib3"])
521+
subprocess.check_call([pycmd, "-m", "ensurepip"] + ([
522+
] if noupgrade else ["--upgrade"]))
523+
subprocess.check_call([pycmd, "-m", "pip", "install"] + ([
524+
] if noupgrade else ["--upgrade"]) + [
525+
"pip", "wheel", "urllib3"])
478526

479527
# install the requirements
480528
branch = get_requirements_branch(version, inst, from_fork)
@@ -506,12 +554,14 @@ def install(inst, version, from_fork):
506554
subprocess.check_call([pycmd, "-m", "pip", "install", "-e", CDIR])
507555
elif version is None: # install the stable version
508556
subprocess.check_call(
509-
[pycmd, "-m", "pip", "install", "--upgrade", "openquake.engine"]
557+
[pycmd, "-m", "pip", "install"] + ([
558+
] if noupgrade else ["--upgrade"]) + ["openquake.engine"]
510559
)
511560
elif re.match(r"\d+(\.\d+)+", version): # install an official version
512561
subprocess.check_call(
513-
[pycmd, "-m", "pip", "install", "--upgrade",
514-
f"openquake.engine{normalize_version(version)}"]
562+
[pycmd, "-m", "pip", "install"] + ([] if noupgrade
563+
else ["--upgrade"]) +
564+
[f"openquake.engine{normalize_version(version)}"]
515565
)
516566
else: # install a branch from github (only for user or server)
517567
commit = latest_commit(version)
@@ -521,8 +571,9 @@ def install(inst, version, from_fork):
521571
custom_env["TMPDIR"] = tmp # Linux/macOS
522572
custom_env["TEMP"] = tmp # Windows
523573
subprocess.check_call(
524-
[pycmd, "-m", "pip", "install",
525-
"--upgrade", GITBRANCH % commit, "--no-clean"],
574+
[pycmd, "-m", "pip", "install"] + (
575+
[] if noupgrade else ["--upgrade"]) + [GITBRANCH % commit,
576+
"--no-clean"],
526577
env=custom_env)
527578
fix_version(commit, inst.VENV)
528579

@@ -553,6 +604,8 @@ def install(inst, version, from_fork):
553604
if inst in (user, devel): # create/upgrade the db in the default location
554605
subprocess.run([oqreal, "engine", "--upgrade-db"])
555606

607+
errors += postinstall_standalone(inst.VENV)
608+
556609
if (
557610
inst is server
558611
and not os.path.exists(inst.OQ)
@@ -646,6 +699,10 @@ def remove(inst):
646699
help="the kind of installation you want",
647700
)
648701
parser.add_argument("--venv", help="venv directory")
702+
parser.add_argument("--novenv", action="store_true",
703+
help="keep the current python environment")
704+
parser.add_argument("--noupgrade", action="store_true",
705+
help="not use '--upgrade' in pip install calls")
649706
parser.add_argument("--remove", action="store_true",
650707
help="disinstall the engine")
651708
parser.add_argument("--version", help="version to install (default stable)")
@@ -663,7 +720,7 @@ def remove(inst):
663720
if args.remove:
664721
remove(inst)
665722
else:
666-
errors = install(inst, args.version, args.from_fork)
723+
errors = install(inst, args.version, args.from_fork, args.novenv, args.noupgrade)
667724
if errors:
668725
# NB: even if one of the tools is missing, the engine will work
669726
sys.exit('\n'.join(errors))
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# -*- coding: utf-8 -*-
2+
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3+
#
4+
# oq-geoviewer
5+
# Copyright (C) 2018-2019 GEM Foundation
6+
#
7+
# oq-geoviewer is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU Affero General Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# oq-geoviewer is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU Affero General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Affero General Public License
18+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
20+
# import subprocess
21+
from django.apps import apps as django_apps
22+
from django.core.management import call_command, get_commands
23+
import sys
24+
from django.core.management.base import BaseCommand
25+
26+
class Command(BaseCommand):
27+
help = ("Command that run a '<app_name>_postinstall' command if it exists")
28+
29+
def add_arguments(self, parser):
30+
parser.add_argument('django_app',
31+
help='django application name')
32+
33+
def handle(self, *args, **options):
34+
found = False
35+
for app in django_apps.get_app_configs():
36+
label = app.label
37+
if options['django_app'] == label:
38+
found = True
39+
break
40+
41+
if not found:
42+
self.stdout.write(
43+
self.style.ERROR(
44+
"No django app '%s' found." % (options['django_app'],))
45+
)
46+
sys.exit(1)
47+
48+
postinstall_cmd = options['django_app'] + '_postinstall'
49+
django_cmds = get_commands()
50+
if postinstall_cmd not in django_cmds:
51+
self.stdout.write(
52+
self.style.WARNING(
53+
"No 'postinst' action needed for app %s, skipped." % (options['django_app'],))
54+
)
55+
sys.exit(0)
56+
57+
call_command(postinstall_cmd)

openquake/server/settings.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,14 @@
230230
# IMPACT_DEFAULT_USGS_ID = 'us7000n7n8' # loadable and convertible rupture
231231
# IMPACT_DEFAULT_USGS_ID = 'us6000jllz' # loadable but with conversion err
232232

233+
# Definition of Django applications
234+
STANDALONE_APP_NAME_MAP = {
235+
'openquakeplatform_ipt': 'ipt',
236+
'django_gem_taxonomy': 'taxonomy',
237+
}
238+
if APPLICATION_MODE != 'TOOLS_ONLY':
239+
STANDALONE_APP_NAME_MAP['openquakeplatform_taxonomy'] = 'glossary'
240+
233241
EXTERNAL_TOOLS = os.environ.get('EXTERNAL_TOOLS', False) == 'True'
234242

235243
# If False, a warning is displayed in case a newer version of the engine has

pyproject.toml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,26 @@ dependencies = [
3232
"django>=4.2, <5",
3333
"psutil",
3434
"requests",
35-
"pyzmq",
35+
"pyzmq~=26.0.3; python_version <= '3.11'",
36+
"pyzmq~=26.2.0; python_version > '3.11'",
3637
"h3>=4.4",
38+
39+
# unplanned deps
40+
"decorator~=5.1.1",
41+
"pillow~=12.2.0",
42+
"toml~=0.10.2",
43+
"numba~=0.61.2",
44+
"alpha_shapes~=1.1.0",
45+
"docutils~=0.19.0",
46+
"django_cors_headers~=4.3.1",
47+
48+
# geopackages
49+
"gdal~=3.11.4; sys_platform == 'win32'",
50+
"gdal~=3.13.1; sys_platform != 'win32'",
51+
"pyproj~=3.7.2",
52+
"geopandas~=1.1.3; sys_platform == 'win32'",
53+
"geopandas~=1.1.4; sys_platform != 'win32'",
54+
"fiona~=1.10.1",
3755
]
3856

3957
[project.urls]

0 commit comments

Comments
 (0)