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

1r""" 

2crate_anon/nlp_webserver/wsgi_app.py 

3 

4=============================================================================== 

5 

6 Copyright (C) 2015, University of Cambridge, Department of Psychiatry. 

7 Created by Rudolf Cardinal (rnc1001@cam.ac.uk). 

8 

9 This file is part of CRATE. 

10 

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. 

15 

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. 

20 

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/>. 

23 

24=============================================================================== 

25 

26Create a WSGI application implementing CRATE's built-in :ref:`NLPRP <nlprp>` 

27server. 

28 

29""" 

30 

31from typing import Dict, Any 

32import logging 

33 

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 

41 

42from crate_anon.nlp_webserver.constants import ( 

43 NlpServerConfigKeys, 

44 SQLALCHEMY_COMMON_OPTIONS, 

45) 

46from crate_anon.nlp_webserver.models import dbsession, Base 

47 

48log = logging.getLogger(__name__) 

49 

50 

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. 

62 

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) 

69 

70 # log.debug(f"global_config: {global_config!r}") 

71 # ... just contains e.g. 'here' (current directory) and '__file__' (config 

72 # filename) 

73 

74 # log.debug(f"settings: {settings!r}") 

75 # ... contains the "[app:main]" section of the config file, as a dict. 

76 

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 

90 

91 # ------------------------------------------------------------------------- 

92 # Pyramid setup 

93 # ------------------------------------------------------------------------- 

94 config = Configurator(settings=settings) 

95 

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) 

105 

106 # Compression 

107 config.add_tween( 

108 "cardinal_pythonlib.pyramid.compression.CompressionTweenFactory" 

109 ) 

110 

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... 

114 

115 # ------------------------------------------------------------------------- 

116 # Create WSGI app 

117 # ------------------------------------------------------------------------- 

118 app = config.make_wsgi_app() 

119 

120 # ------------------------------------------------------------------------- 

121 # Register processors 

122 # ------------------------------------------------------------------------- 

123 from crate_anon.nlp_webserver.procs import ServerProcessor # noqa: F401 

124 

125 return app