diff --git a/python/Dockerfile b/python/Dockerfile index 212c3c53..f31d7f2c 100644 --- a/python/Dockerfile +++ b/python/Dockerfile @@ -7,10 +7,12 @@ WORKDIR /app RUN apk add --update --no-cache gcc python3-dev build-base libev-dev libffi-dev bash COPY requirements.txt /app -RUN pip3 install -r requirements.txt +RUN pip3 install --no-cache-dir -r requirements.txt + +ENV WSGI_FRAMEWORK GEVENT COPY *.py /app ENV PYTHONUNBUFFERED 1 -ENTRYPOINT ["python3"] -CMD ["server.py"] + +CMD [ "gunicorn", "--bind=0.0.0.0:8888", "--timeout", "900", "-k", "gevent", "-w", "2", "server:app" ] diff --git a/python/requirements.txt b/python/requirements.txt index 02c3a767..4066018e 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1,13 +1,11 @@ -bjoern==3.2.1 +gunicorn==20.1.0 blinker==1.4 certifi==2021.10.8 chardet==4.0.0 charset-normalizer==2.0.7 click==8.0.3 Flask==2.1.1 -gevent==21.12.0 -gevent-ws==2.1.0 -greenlet==1.1.2 +gevent==22.10.2 hiredis==2.0.0 httplib2==0.20.1 idna==3.3 @@ -17,7 +15,6 @@ Jinja2==3.0.2 MarkupSafe==2.0.1 pyparsing==2.4.7 python-dateutil==2.8.2 -redis==3.5.3 requests==2.26.0 sentry-sdk==1.5.10 six==1.16.0 @@ -26,3 +23,6 @@ Werkzeug==2.0.2 zipp==3.8.0 zope.event==4.5.0 zope.interface==5.4.0 + +# libraries required by users +boto3==1.26.156 \ No newline at end of file diff --git a/python/server.py b/python/server.py index 4485c3bc..908a81a1 100644 --- a/python/server.py +++ b/python/server.py @@ -7,8 +7,6 @@ import json from flask import Flask, request, abort -from gevent.pywsgi import WSGIServer -import bjoern import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration @@ -110,8 +108,14 @@ def healthz(self): def userfunc_call(self, *args): if self.userfunc is None: - self.logger.error('userfunc is None') - return abort(500) + if check_specialize_info_exists(): + self.logger.info('Found state.json') + specialize_info = read_specialize_info() + self.userfunc = self._load_v2(specialize_info) + self.logger.info('Loaded user function {}'.format(specialize_info)) + else: + self.logger.error('userfunc is None') + return abort(500) return self.userfunc(*args) def _load_v2(self, specialize_info): @@ -163,39 +167,21 @@ def signal_handler(self, signalnum, frame): raise SignalExit(signalnum) -def main(): - app = FuncApp(__name__, logging.DEBUG) - sockets = Sockets(app) - register_signal_handlers(app.signal_handler) - - app.add_url_rule('/specialize', 'load', app.load, methods=['POST']) - app.add_url_rule('/v2/specialize', 'loadv2', app.loadv2, methods=['POST']) - app.add_url_rule('/healthz', 'healthz', app.healthz, methods=['GET']) - app.add_url_rule( - '/', - 'userfunc_call', - app.userfunc_call, - methods=['GET', 'POST', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']) - sockets.add_url_rule( - '/', - 'userfunc_call', - app.userfunc_call, - methods=['GET', 'POST', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']) - - # - # TODO: this starts the built-in server, which isn't the most - # efficient. We should use something better. - # - if os.environ.get("WSGI_FRAMEWORK") == "GEVENT": - app.logger.info("Starting gevent based server") - from gevent_ws import WebSocketHandler - svc = WSGIServer(('0.0.0.0', RUNTIME_PORT), - app, - handler_class=WebSocketHandler) - svc.serve_forever() - else: - app.logger.info("Starting bjoern based server") - bjoern.run(app, '0.0.0.0', RUNTIME_PORT, reuse_port=True) - -main() +app = FuncApp(__name__, logging.DEBUG) +sockets = Sockets(app) +register_signal_handlers(app.signal_handler) + +app.add_url_rule('/specialize', 'load', app.load, methods=['POST']) +app.add_url_rule('/v2/specialize', 'loadv2', app.loadv2, methods=['POST']) +app.add_url_rule('/healthz', 'healthz', app.healthz, methods=['GET']) +app.add_url_rule( + '/', + 'userfunc_call', + app.userfunc_call, + methods=['GET', 'POST', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']) +sockets.add_url_rule( + '/', + 'userfunc_call', + app.userfunc_call, + methods=['GET', 'POST', 'PUT', 'HEAD', 'OPTIONS', 'DELETE'])