-
Notifications
You must be signed in to change notification settings - Fork 85
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
Create debian templates for the python 3 flask templates. #26
Changes from all commits
f010bca
d45361d
f783f83
d819389
2235606
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,56 @@ | ||||||
FROM openfaas/of-watchdog:0.7.2 as watchdog | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
FROM python:3.7-slim-buster | ||||||
|
||||||
COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog | ||||||
RUN chmod +x /usr/bin/fwatchdog | ||||||
|
||||||
ARG ADDITIONAL_PACKAGE | ||||||
# Alternatively use ADD https:// (which will not be cached by Docker builder) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this comment now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
RUN apt-get -qy update && apt-get -qy install gcc make ${ADDITIONAL_PACKAGE} | ||||||
|
||||||
# Add non root user | ||||||
RUN addgroup --system app && adduser app --system --ingroup app | ||||||
RUN chown app /home/app | ||||||
|
||||||
USER app | ||||||
|
||||||
ENV PATH=$PATH:/home/app/.local/bin | ||||||
|
||||||
WORKDIR /home/app/ | ||||||
|
||||||
COPY index.py . | ||||||
COPY requirements.txt . | ||||||
|
||||||
USER root | ||||||
RUN pip install -r requirements.txt | ||||||
|
||||||
#build function directory and install user specified componenets. | ||||||
USER app | ||||||
|
||||||
RUN mkdir -p function | ||||||
RUN touch ./function/__init__.py | ||||||
WORKDIR /home/app/function/ | ||||||
COPY function/requirements.txt . | ||||||
RUN pip install --user -r requirements.txt | ||||||
|
||||||
WORKDIR /home/app/ | ||||||
|
||||||
#install function code | ||||||
USER root | ||||||
|
||||||
COPY function function | ||||||
RUN chown -R app:app ./ | ||||||
|
||||||
#configure WSGI server and healthcheck | ||||||
USER app | ||||||
|
||||||
ENV fprocess="python index.py" | ||||||
|
||||||
ENV cgi_headers="true" | ||||||
ENV mode="http" | ||||||
ENV upstream_url="http://127.0.0.1:5000" | ||||||
|
||||||
HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1 | ||||||
|
||||||
CMD ["fwatchdog"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
def handle(req): | ||
"""handle a request to the function | ||
Args: | ||
req (str): request body | ||
""" | ||
|
||
return req |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Copyright (c) Alex Ellis 2017. All rights reserved. | ||
# Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
from flask import Flask, request | ||
from function import handler | ||
#from gevent.wsgi import WSGIServer | ||
from gevent.pywsgi import WSGIServer | ||
|
||
app = Flask(__name__) | ||
|
||
@app.before_request | ||
def fix_transfer_encoding(): | ||
""" | ||
Sets the "wsgi.input_terminated" environment flag, thus enabling | ||
Werkzeug to pass chunked requests as streams. The gunicorn server | ||
should set this, but it's not yet been implemented. | ||
""" | ||
|
||
transfer_encoding = request.headers.get("Transfer-Encoding", None) | ||
if transfer_encoding == u"chunked": | ||
request.environ["wsgi.input_terminated"] = True | ||
|
||
@app.route("/", defaults={"path": ""}, methods=["POST", "GET"]) | ||
@app.route("/<path:path>", methods=["POST", "GET"]) | ||
def main_route(path): | ||
ret = handler.handle(request.get_data()) | ||
return ret | ||
|
||
if __name__ == '__main__': | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we are using
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... well, ok. But that kind of represents a change to all of the templates, which is out of the scope of this PR> That's probably better as a new issue, especially because I at least don't know any implications for using a newer version of gevent.. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain what "we should money patch" means? 🤔 I would say this is also out of scope since the task was to port from Alpine to Debian. Happy for you to raise an issue Vivek if you can explain in a bit more detail there? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gevent is built on top of libevent/libev (for asynchronous I/O) and greenlets (lightweight cooperative multi-threading). Greenlets are based on Stackless Python. Greenlets has no implicit scheduling and we can control exactly when our code runs. In case of I/O block, the code will automatically switch to other I/O or wait for acknowledgment, however the standard libraries implementation does not work that way. Monkey patching is required to patch the standard library with compatible cooperative counterparts from gevent package. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that, this is out of scope of this PR. I will raise a separate issue. |
||
http_server = WSGIServer(('0.0.0.0', 5000), app) | ||
http_server.serve_forever() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
flask | ||
gevent | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
language: python3-flask-debian | ||
fprocess: python index.py |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -5,6 +5,8 @@ COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog | |||
RUN chmod +x /usr/bin/fwatchdog | ||||
|
||||
ARG ADDITIONAL_PACKAGE | ||||
# Alternatively use ADD https:// (which will not be cached by Docker builder) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||
|
||||
RUN apk --no-cache add musl-dev gcc make ${ADDITIONAL_PACKAGE} | ||||
|
||||
# Add non root user | ||||
|
@@ -19,8 +21,11 @@ WORKDIR /home/app/ | |||
|
||||
COPY index.py . | ||||
COPY requirements.txt . | ||||
|
||||
USER root | ||||
RUN pip install -r requirements.txt | ||||
|
||||
#build function directory and install user specified componenets. | ||||
USER app | ||||
|
||||
RUN mkdir -p function | ||||
|
@@ -31,9 +36,13 @@ RUN pip install --user -r requirements.txt | |||
|
||||
WORKDIR /home/app/ | ||||
|
||||
#install function code | ||||
USER root | ||||
|
||||
COPY function function | ||||
RUN chown -R app:app ./ | ||||
|
||||
#configure WSGI server and healthcheck | ||||
USER app | ||||
|
||||
ENV fprocess="python index.py" | ||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,49 @@ | ||||||
FROM openfaas/of-watchdog:0.7.2 as watchdog | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have 0.7.7 now but this can be changed after. https://github.com/openfaas-incubator/of-watchdog/releases/tag/0.7.7 |
||||||
FROM python:3.7-slim-buster | ||||||
|
||||||
COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog | ||||||
RUN chmod +x /usr/bin/fwatchdog | ||||||
|
||||||
ARG ADDITIONAL_PACKAGE | ||||||
# Alternatively use ADD https:// (which will not be cached by Docker builder) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs to be removed. I made this comment earlier |
||||||
|
||||||
RUN apt-get -qy update && apt-get -qy install ${ADDITIONAL_PACKAGE} | ||||||
|
||||||
# Add non root user | ||||||
RUN addgroup --system app && adduser app --system --ingroup app | ||||||
RUN chown app /home/app | ||||||
|
||||||
USER app | ||||||
|
||||||
ENV PATH=$PATH:/home/app/.local/bin | ||||||
|
||||||
WORKDIR /home/app/ | ||||||
|
||||||
COPY index.py . | ||||||
COPY requirements.txt . | ||||||
USER root | ||||||
RUN pip install -r requirements.txt | ||||||
USER app | ||||||
|
||||||
RUN mkdir -p function | ||||||
RUN touch ./function/__init__.py | ||||||
WORKDIR /home/app/function/ | ||||||
COPY function/requirements.txt . | ||||||
RUN pip install --user -r requirements.txt | ||||||
|
||||||
WORKDIR /home/app/ | ||||||
|
||||||
USER root | ||||||
COPY function function | ||||||
RUN chown -R app:app ./ | ||||||
USER app | ||||||
|
||||||
# Set up of-watchdog for HTTP mode | ||||||
ENV fprocess="python index.py" | ||||||
ENV cgi_headers="true" | ||||||
ENV mode="http" | ||||||
ENV upstream_url="http://127.0.0.1:5000" | ||||||
|
||||||
HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1 | ||||||
|
||||||
CMD ["fwatchdog"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
def handle(event, context): | ||
return { | ||
"statusCode": 200, | ||
"body": "Hello from OpenFaaS!" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we have this echo the request body, like in the default flask template handler There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, I'm matching the existing templates. This is what the default http header does, so I don't want to change that. I don't want to change anything about these templates across the board. I just want to make the debian ones available and functional. At least under this PR. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/usr/bin/env python | ||
from flask import Flask, request, jsonify | ||
from waitress import serve | ||
import os | ||
|
||
from function import handler | ||
|
||
app = Flask(__name__) | ||
|
||
class Event: | ||
def __init__(self): | ||
self.body = request.get_data() | ||
self.headers = request.headers | ||
self.method = request.method | ||
self.query = request.args | ||
self.path = request.path | ||
|
||
class Context: | ||
def __init__(self): | ||
self.hostname = os.environ['HOSTNAME'] | ||
|
||
def format_status_code(resp): | ||
if 'statusCode' in resp: | ||
return resp['statusCode'] | ||
|
||
return 200 | ||
|
||
def format_body(resp): | ||
if 'body' not in resp: | ||
return "" | ||
elif type(resp['body']) == dict: | ||
return jsonify(resp['body']) | ||
else: | ||
return str(resp['body']) | ||
|
||
def format_headers(resp): | ||
if 'headers' not in resp: | ||
return [] | ||
elif type(resp['headers']) == dict: | ||
headers = [] | ||
for key in resp['headers'].keys(): | ||
header_tuple = (key, resp['headers'][key]) | ||
headers.append(header_tuple) | ||
return headers | ||
|
||
return resp['headers'] | ||
|
||
def format_response(resp): | ||
if resp == None: | ||
return ('', 200) | ||
|
||
statusCode = format_status_code(resp) | ||
body = format_body(resp) | ||
headers = format_headers(resp) | ||
|
||
return (body, statusCode, headers) | ||
|
||
@app.route('/', defaults={'path': ''}, methods=['GET', 'PUT', 'POST', 'PATCH', 'DELETE']) | ||
@app.route('/<path:path>', methods=['GET', 'PUT', 'POST', 'PATCH', 'DELETE']) | ||
def call_handler(path): | ||
event = Event() | ||
context = Context() | ||
response_data = handler.handle(event, context) | ||
|
||
resp = format_response(response_data) | ||
return resp | ||
|
||
if __name__ == '__main__': | ||
serve(app, host='0.0.0.0', port=5000) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
flask | ||
waitress |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
language: python3-http-debian | ||
fprocess: python index.py |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the latest version?