Coverage for nlp_webserver/wsgi_app.py: 42%
31 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-08-27 10:34 -0500
« prev ^ index » next coverage.py v7.8.0, created at 2025-08-27 10:34 -0500
1r"""
2crate_anon/nlp_webserver/wsgi_app.py
4===============================================================================
6 Copyright (C) 2015, University of Cambridge, Department of Psychiatry.
7 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
9 This file is part of CRATE.
11 CRATE is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 CRATE is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with CRATE. If not, see <https://www.gnu.org/licenses/>.
24===============================================================================
26Create a WSGI application implementing CRATE's built-in :ref:`NLPRP <nlprp>`
27server.
29"""
31from typing import Dict, Any
32import logging
34from cardinal_pythonlib.logs import main_only_quicksetup_rootlogger
35from cardinal_pythonlib.sqlalchemy.session import get_safe_url_from_engine
36from pyramid.config import Router
37from pyramid.authentication import AuthTktAuthenticationPolicy
38from pyramid.authorization import ACLAuthorizationPolicy
39from pyramid.config import Configurator
40from sqlalchemy import engine_from_config
42from crate_anon.nlp_webserver.constants import (
43 NlpServerConfigKeys,
44 SQLALCHEMY_COMMON_OPTIONS,
45)
46from crate_anon.nlp_webserver.models import dbsession, Base
48log = logging.getLogger(__name__)
51# noinspection PyUnusedLocal
52def make_wsgi_app(global_config: Dict[Any, Any], **settings) -> Router:
53 """
54 Creates the WSGI application used for the CRATE NLPRP web server.
55 """
56 # This function is typically called from:
57 #
58 # - pyramid/scripts/pserve.py
59 # - to paste/deploy/loadwsgi.py
60 # - to paste/deploy/util.py
61 # - to here.
63 # -------------------------------------------------------------------------
64 # Logging
65 # -------------------------------------------------------------------------
66 main_only_quicksetup_rootlogger(level=logging.DEBUG)
67 # ... necessary given our route in, as above.
68 logging.getLogger("sqlalchemy").setLevel(logging.WARNING)
70 # log.debug(f"global_config: {global_config!r}")
71 # ... just contains e.g. 'here' (current directory) and '__file__' (config
72 # filename)
74 # log.debug(f"settings: {settings!r}")
75 # ... contains the "[app:main]" section of the config file, as a dict.
77 # -------------------------------------------------------------------------
78 # Database
79 # -------------------------------------------------------------------------
80 engine = engine_from_config(
81 settings, # eventually reads e.g. "sqlalchemy.url"
82 NlpServerConfigKeys.SQLALCHEMY_PREFIX,
83 **SQLALCHEMY_COMMON_OPTIONS,
84 )
85 # ... add to config - pool_recycle is set to create new sessions every 7h
86 sqla_url = get_safe_url_from_engine(engine)
87 log.info(f"Using database {sqla_url!r}")
88 dbsession.configure(bind=engine)
89 Base.metadata.bind = engine
91 # -------------------------------------------------------------------------
92 # Pyramid setup
93 # -------------------------------------------------------------------------
94 config = Configurator(settings=settings)
96 # Security policies
97 authn_policy = AuthTktAuthenticationPolicy(
98 settings[NlpServerConfigKeys.NLP_WEBSERVER_SECRET],
99 secure=True, # only allow requests over HTTPS
100 hashalg="sha512",
101 )
102 authz_policy = ACLAuthorizationPolicy()
103 config.set_authentication_policy(authn_policy)
104 config.set_authorization_policy(authz_policy)
106 # Compression
107 config.add_tween(
108 "cardinal_pythonlib.pyramid.compression.CompressionTweenFactory"
109 )
111 # Routes
112 config.add_route("index", "/") # route URL path / to a view named "index"
113 config.scan(".views") # scan views.py in this directory for @view...
115 # -------------------------------------------------------------------------
116 # Create WSGI app
117 # -------------------------------------------------------------------------
118 app = config.make_wsgi_app()
120 # -------------------------------------------------------------------------
121 # Register processors
122 # -------------------------------------------------------------------------
123 from crate_anon.nlp_webserver.procs import ServerProcessor # noqa: F401
125 return app