Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updated sa_gunicorn #828

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 44 additions & 48 deletions py4web/server_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,24 +121,17 @@ def get_workers(opts, default=10):
except KeyError:
return default


# ---------------------- servers -----------------------------------------------
def gunicorn():

def gunicorn():
from gevent import local # pip install gevent gunicorn
import threading

if isinstance(threading.local(), local.local):
print("gunicorn: monkey.patch_all() applied")

class GunicornServer(ServerAdapter):
""" https://docs.gunicorn.org/en/stable/settings.html """

# ./py4web.py run apps -s gunicorn --watch=off --ssl_cert=cert.pem --ssl_key=key.pem -w 6 -L 20
# ./py4web.py run apps -s gunicornGevent --watch=off --ssl_cert=cert.pem --ssl_key=key.pem -w 6 -L 20
# time seq 1 5000 | xargs -I % -P 0 curl http://localhost:8000/todo &>/dev/null

def run(self, app_handler):
def run(self, py4web_apps_handler):
from gunicorn.app.base import Application
import re

Expand All @@ -151,10 +144,11 @@ def run(self, app_handler):
"keyfile": self.options.get("keyfile", None),
"accesslog": None,
"errorlog": None,
"config": "sa_config",
# ( 'sa_config', 'GUNICORN_', 'gunicorn.saenv', 'gunicorn.conf.py' )
}

if not self.quiet:

level = check_level(self.options["logging_level"])
log_file = get_log_file(out_banner=False)

Expand All @@ -171,26 +165,34 @@ def run(self, app_handler):
)

class GunicornApplication(Application):
def logger_info(self, msg="msg"):
def logger_info(self, msg="its logger_info"):
logger and logger.info(str(msg))

def get_gunicorn_vars(self, env_file="gunicorn.saenv", env_key='GUNICORN_'):
def get_gunicorn_options(
self,
default="gunicorn.conf.py",
env_file="gunicorn.saenv",
env_key="GUNICORN_",
):
def check_kv(kx, vx):
if kx and vx and kx != "bind":
bad_keys = (
"bind",
"config",
)
if kx and vx and kx not in bad_keys:
if vx.startswith("{") and vx.endswith("}"):
vt = re.sub(r",\s*\}", "}", vx)
vt = re.sub("r'\,\s*\}'", "}", vx)
vx = json.loads(vt.replace("'", '"'))
if vx == "None":
vx = None
return kx, vx
self.logger_info(f"gunicorn: Bad {kx}:{vx}")
return None, None

result = dict()
if os.path.isfile(default):
return {"use_python_config": default, "config": default}

default_conf = './gunicorn.conf.py'
if os.path.isfile( default_conf ):
result ['use_python_config' ] = default_conf
return result
gu_opts = dict()

if os.path.isfile(env_file):
try:
Expand All @@ -200,7 +202,7 @@ def check_kv(kx, vx):
line = line.strip()
if not line or line.startswith(("#", "[")):
continue
for e in ("export ", env_key ):
for e in ("export ", env_key):
line = line.replace(e, "", 1)
k, v = None, None
try:
Expand All @@ -211,52 +213,45 @@ def check_kv(kx, vx):
k, v = check_kv(k, v)
if k is None:
continue
result[k] = v
if result:
result["config"] = "./" + env_file
return result
gu_opts[k] = v
if gu_opts:
gu_opts["config"] = env_file
return gu_opts
except OSError as ex:
self.logger_info(f"gunicorn: cannot read {env_file}; {ex}")
self.logger_info(f"gunicorn: Bad {env_file}; {ex}")

for k, v in os.environ.items():
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
gu_opts[k] = v

result["config"] = env_key
return result
if gu_opts:
gu_opts["config"] = env_key
return gu_opts

def load_config(self):

gunicorn_vars = self.get_gunicorn_vars()

# test https://github.com/benoitc/gunicorn/blob/master/examples/example_config.py
for e in ("use_python_config", "use_native_config"):
try:
location = gunicorn_vars[e]
Application.load_config_from_module_name_or_filename(
self, location
)
self.cfg.set("config", "./" + location)
self.logger_info(f"gunicorn: used {location}")
return
except KeyError:
pass

sa_config.update(gunicorn_vars)
location = gunicorn_vars["config"]
self.logger_info(f"gunicorn: used {location} {sa_config}")
sa_config.update(self.get_gunicorn_options())

for k, v in sa_config.items():
if k not in self.cfg.settings:
continue
self.cfg.set(k, v)

if "print_config" in sa_config:
if sa_config["print_config"] == "True":
self.logger_info(sa_config)
self.logger_info(self.cfg)

for e in ("use_python_config", "use_native_config"):
if e in sa_config:
filename = sa_config[e]
Application.load_config_from_file(self, filename)

def load(self):
return app_handler
return py4web_apps_handler

GunicornApplication().run()

Expand All @@ -266,6 +261,7 @@ def load(self):
gunicornGevent = gunicorn



def gevent():
# gevent version 23.9.1

Expand Down
Loading