From b2193b341322f65caddd3f5df846660e51c3db13 Mon Sep 17 00:00:00 2001 From: Alex Bsk Date: Thu, 9 Nov 2023 08:35:16 +0300 Subject: [PATCH] set gunicorn.conf.py as default (#825) --- py4web/gunicorn.rst | 51 +++++++++++++++++++++++++++++++++++---- py4web/server_adapters.py | 29 +++++++++------------- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/py4web/gunicorn.rst b/py4web/gunicorn.rst index d4dde8775..12be44e9d 100644 --- a/py4web/gunicorn.rst +++ b/py4web/gunicorn.rst @@ -16,7 +16,7 @@ gunicornGevent === gunicorn + monkey.patch_all() It is possible to use several methods to configure gunicorn options with py4web -Let's show examples +Let's show examples (go to py4web root dir) * set gunicorn options via bash environment variables @@ -41,14 +41,14 @@ Let's show examples :: - # example gunicorn.saenv + # example file gunicorn.saenv # export GUNICORN_worker_tmp_dir=/dev/shm export GUNICORN_max_requests=1200 worker_class=gthread threads=2 - # guncornGevent + # gunicornGevent #worker_class=gevent #worker_class=eventlet @@ -79,8 +79,9 @@ Let's show examples .. code:: python - # Gunicorn configuration file + # Gunicorn configuration file myguni.conf.py # https://docs.gunicorn.org/en/stable/settings.html + import multiprocessing max_requests = 1000 @@ -99,7 +100,7 @@ Let's show examples :: - write python module + create a new python module mod_name .. code:: bash @@ -117,3 +118,43 @@ Let's show examples $ ./py4web.py run apps -s gunicorn --watch=off + +* set gunicorn options via gunicorn.conf.py + + :: + + + put gunicorn settings in the gunicorn.conf.py + + (if gunicorn.conf.py exists, the GUNICORN_ vars and file gunicorn.saenv will be ignored) + + .. code:: bash + + $ echo "print_config = True" > gunicorn.conf.py + + + :: + + $ ./py4web.py run apps -s gunicorn --watch=off + +* set gunicorn options via gunicorn-cli + + :: + + run py4web/apps as wsgi-app + + .. code:: bash + + $ echo 'from py4web.core import wsgi;myapp = wsgi(apps_folder="apps")' > py4web_wsgi.py + $ + + + :: + + $ gunicorn -w 4 py4web_wsgi:myapp + + + + +thats it + diff --git a/py4web/server_adapters.py b/py4web/server_adapters.py index 1d63e36e6..4a8db2143 100644 --- a/py4web/server_adapters.py +++ b/py4web/server_adapters.py @@ -174,7 +174,7 @@ class GunicornApplication(Application): def logger_info(self, msg="msg"): logger and logger.info(str(msg)) - def get_gunicorn_vars(self, env_file="gunicorn.saenv"): + def get_gunicorn_vars(self, env_file="gunicorn.saenv", env_key='GUNICORN_'): def check_kv(kx, vx): if kx and vx and kx != "bind": if vx.startswith("{") and vx.endswith("}"): @@ -186,6 +186,12 @@ def check_kv(kx, vx): return None, None result = dict() + + default_conf = './gunicorn.conf.py' + if os.path.isfile( default_conf ): + result ['use_python_config' ] = default_conf + return result + if os.path.isfile(env_file): try: with open(env_file, "r") as f: @@ -194,7 +200,7 @@ def check_kv(kx, vx): line = line.strip() if not line or line.startswith(("#", "[")): continue - for e in ("export ", "GUNICORN_"): + for e in ("export ", env_key ): line = line.replace(e, "", 1) k, v = None, None try: @@ -213,13 +219,14 @@ def check_kv(kx, vx): self.logger_info(f"gunicorn: cannot read {env_file}; {ex}") for k, v in os.environ.items(): - if k.startswith("GUNICORN_"): + if k.startswith(env_key): k = k.split("_", 1)[1].lower() k, v = check_kv(k, v) if k is None: continue result[k] = v - result["config"] = "os.environ.items" + + result["config"] = env_key return result def load_config(self): @@ -239,7 +246,6 @@ def load_config(self): except KeyError: pass - #if gunicorn_vars: sa_config.update(gunicorn_vars) location = gunicorn_vars["config"] self.logger_info(f"gunicorn: used {location} {sa_config}") @@ -247,18 +253,7 @@ def load_config(self): for k, v in sa_config.items(): if k not in self.cfg.settings: continue - try: - self.cfg.set(k, v) - except Exception: - self.logger_info(f"gunicorn: Invalid value for {k}:{v}") - raise - - try: - gunicorn_vars["print_config"] == "True" and self.logger_info( - self.cfg - ) - except KeyError: - pass + self.cfg.set(k, v) def load(self): return app_handler