wsgi.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import multiprocessing
  2. import os
  3. import yaml
  4. # DO NOT load env_setup here. It must be loaded after workers have been forked.
  5. from lakesuperior.config_parser import default_config_dir, parse_config
  6. __doc__ = """
  7. GUnicorn WSGI configuration.
  8. GUnicorn reads configuration options from this file by importing it::
  9. gunicorn -c python:lakesuperior.wsgi lakesuperior.server:fcrepo
  10. This module reads the ``gunicorn.yml`` configuration and overrides defaults
  11. set here. Only some of the GUnicorn optionscan be changed: others have to be
  12. set to specific values in order for Lakesuperior to work properly.
  13. """
  14. __all__ = [
  15. 'bind',
  16. 'workers',
  17. 'worker_class',
  18. 'max_requests',
  19. 'user',
  20. 'group',
  21. 'raw_env',
  22. 'preload_app',
  23. 'daemon',
  24. 'reload',
  25. 'pidfile',
  26. 'accesslog',
  27. 'errorlog',
  28. ]
  29. """
  30. Variables to export to GUnicorn.
  31. Not sure if this does anything—GUnicorn doesn't seem to use ``import *``—but
  32. at least good for maintainers of this code.
  33. """
  34. main_config = parse_config()
  35. class __Defaults:
  36. """
  37. Gather default values for WSGI config.
  38. """
  39. config_file = os.path.join(default_config_dir, 'gunicorn.yml')
  40. listen_addr = '0.0.0.0'
  41. listen_port = 8000
  42. preload_app = False
  43. app_mode = 'prod'
  44. worker_class = 'sync'
  45. max_requests = 0
  46. def __init__(self):
  47. with open(self.config_file, 'r') as fh:
  48. self.config = yaml.load(fh, yaml.SafeLoader)
  49. oldwd = os.getcwd()
  50. os.chdir(main_config['application']['data_dir'])
  51. # Set data directory relatively to startup script.
  52. self.data_dir = os.path.realpath(self.config.get('data_dir'))
  53. os.chdir(oldwd)
  54. self.run_dir = os.path.join(self.data_dir, 'run')
  55. self.log_dir = os.path.join(self.data_dir, 'log')
  56. os.makedirs(self.log_dir, exist_ok=True)
  57. os.makedirs(self.run_dir, exist_ok=True)
  58. self.workers = (multiprocessing.cpu_count() * 2) + 1
  59. __def = __Defaults()
  60. __app_mode = main_config['application'].get('app_mode', __def.app_mode)
  61. # Exposed Gunicorn parameters begin here.
  62. bind = '{}:{}'.format(
  63. __def.config.get('listen_addr', __def.listen_addr),
  64. __def.config.get('listen_port', __def.listen_port))
  65. workers = __def.config.get('workers', __def.workers)
  66. worker_class = __def.config.get('worker_class', __def.worker_class)
  67. max_requests = __def.config.get('max_requests', __def.max_requests)
  68. user = __def.config.get('user')
  69. group = __def.config.get('group')
  70. raw_env = 'APP_MODE={}'.format(__app_mode)
  71. preload_app = __def.config.get('preload_app', __def.preload_app)
  72. #daemon = __app_mode == 'prod'
  73. reload = __app_mode == 'dev' and not preload_app
  74. pidfile = os.path.join(__def.run_dir, 'fcrepo.pid')
  75. accesslog = os.path.join(__def.log_dir, 'gunicorn-access.log')
  76. errorlog = os.path.join(__def.log_dir, 'gunicorn-error.log')
  77. print('\nLoading WSGI server with configuration:')
  78. for prop in __all__:
  79. print(f'{prop:>16} = {locals().get(prop)}')
  80. print('\n')