Changed crystal template, picked latest flask one
This commit is contained in:
parent
f2be91d628
commit
1cc3ef2e82
1
.gitignore
vendored
1
.gitignore
vendored
@ -163,3 +163,4 @@ cython_debug/
|
|||||||
.vscode/
|
.vscode/
|
||||||
build
|
build
|
||||||
.secrets
|
.secrets
|
||||||
|
|
||||||
|
@ -16,6 +16,6 @@ functions:
|
|||||||
handler: ./tapas
|
handler: ./tapas
|
||||||
image: ralsina/tapas:latest
|
image: ralsina/tapas:latest
|
||||||
tapas2:
|
tapas2:
|
||||||
lang: crystal-http
|
lang: crystal
|
||||||
handler: ./tapas2
|
handler: ./tapas2
|
||||||
image: ralsina/tapas2:latest
|
image: ralsina/tapas2:latest
|
||||||
|
@ -1,21 +1,7 @@
|
|||||||
require "http/request"
|
require "json"
|
||||||
require "http/headers"
|
|
||||||
|
|
||||||
class Handler
|
class Handler
|
||||||
def run(request : HTTP::Request)
|
def run(req : String)
|
||||||
|
return JSON::Any.new("Hello, Crystal. You said: #{req}")
|
||||||
if request.body.nil?
|
|
||||||
return {
|
|
||||||
body: "Foo",
|
|
||||||
status_code: 200,
|
|
||||||
headers: HTTP::Headers{"Content-Type" => "text/plain"},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
{
|
|
||||||
body: "Hello, Crystal. You said: #{request.body.try(&.gets_to_end)}",
|
|
||||||
status_code: 200,
|
|
||||||
headers: HTTP::Headers{"Content-Type" => "text/plain"},
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,2 +1,7 @@
|
|||||||
name: crystal-http-template
|
name: crystal_faas_function
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
|
|
||||||
|
# dependencies:
|
||||||
|
# pg:
|
||||||
|
# github: will/crystal-pg
|
||||||
|
# version: "~> 0.5"
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
FROM ghcr.io/openfaas/of-watchdog:0.9.11 as watchdog
|
|
||||||
|
|
||||||
FROM crystallang/crystal:1.8.2
|
|
||||||
|
|
||||||
COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog
|
|
||||||
RUN chmod +x /usr/bin/fwatchdog
|
|
||||||
|
|
||||||
ARG ADDITIONAL_PACKAGE
|
|
||||||
RUN apt-get update \
|
|
||||||
&& apt-get install -qy --no-install-recommends ${ADDITIONAL_PACKAGE}
|
|
||||||
|
|
||||||
WORKDIR /home/app
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
COPY function/shard.yml shard.yml
|
|
||||||
RUN shards install
|
|
||||||
RUN crystal build main.cr -o handler --release
|
|
||||||
|
|
||||||
# Create a non-root user
|
|
||||||
RUN addgroup --system app \
|
|
||||||
&& adduser --system --ingroup app app
|
|
||||||
|
|
||||||
RUN chown app:app -R /home/app
|
|
||||||
|
|
||||||
USER app
|
|
||||||
|
|
||||||
WORKDIR /home/app
|
|
||||||
|
|
||||||
ENV fprocess="./handler"
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
HEALTHCHECK --interval=2s CMD [ -e /tmp/.lock ] || exit 1
|
|
||||||
|
|
||||||
ENV upstream_url="http://127.0.0.1:5000"
|
|
||||||
ENV mode="http"
|
|
||||||
|
|
||||||
CMD ["fwatchdog"]
|
|
@ -1,12 +0,0 @@
|
|||||||
require "http/request"
|
|
||||||
require "http/headers"
|
|
||||||
|
|
||||||
class Handler
|
|
||||||
def run(request : HTTP::Request)
|
|
||||||
{
|
|
||||||
body: "Hello, Crystal. You said: #{request.body.try(&.gets_to_end)}",
|
|
||||||
status_code: 200,
|
|
||||||
headers: HTTP::Headers{"Content-Type" => "text/plain"},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,2 +0,0 @@
|
|||||||
name: crystal-http-template
|
|
||||||
version: 0.1.0
|
|
@ -1,41 +0,0 @@
|
|||||||
require "http/server"
|
|
||||||
require "./function/handler"
|
|
||||||
|
|
||||||
server = HTTP::Server.new do |context|
|
|
||||||
response_triple : NamedTuple(body: String, headers: HTTP::Headers, status_code: Int32) |
|
|
||||||
NamedTuple(body: String, headers: HTTP::Headers) |
|
|
||||||
NamedTuple(body: String, status_code: Int32) |
|
|
||||||
NamedTuple(body: String) |
|
|
||||||
NamedTuple(headers: HTTP::Headers, status_code: Int32) |
|
|
||||||
NamedTuple(headers: HTTP::Headers) |
|
|
||||||
NamedTuple(status_code: Int32)
|
|
||||||
|
|
||||||
handler = Handler.new
|
|
||||||
response_triple = handler.run(context.request)
|
|
||||||
|
|
||||||
if response_triple.is_a?(NamedTuple(body: String, headers: HTTP::Headers, status_code: Int32) |
|
|
||||||
NamedTuple(body: String, status_code: Int32) |
|
|
||||||
NamedTuple(headers: HTTP::Headers, status_code: Int32) |
|
|
||||||
NamedTuple(status_code: Int32))
|
|
||||||
context.response.status_code = response_triple[:status_code]
|
|
||||||
end
|
|
||||||
|
|
||||||
if response_triple.is_a?(NamedTuple(body: String, headers: HTTP::Headers, status_code: Int32) |
|
|
||||||
NamedTuple(body: String, headers: HTTP::Headers) |
|
|
||||||
NamedTuple(headers: HTTP::Headers, status_code: Int32) |
|
|
||||||
NamedTuple(headers: HTTP::Headers))
|
|
||||||
response_triple[:headers].each do |key, value|
|
|
||||||
context.response.headers[key] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if response_triple.is_a?(NamedTuple(body: String, headers: HTTP::Headers, status_code: Int32) |
|
|
||||||
NamedTuple(body: String, headers: HTTP::Headers) |
|
|
||||||
NamedTuple(body: String, status_code: Int32) |
|
|
||||||
NamedTuple(body: String))
|
|
||||||
context.response.print(response_triple[:body])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
server.bind_tcp "0.0.0.0", 5000
|
|
||||||
server.listen
|
|
38
template/crystal/Dockerfile
Normal file
38
template/crystal/Dockerfile
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
FROM crystallang/crystal:1.8.0 as builder
|
||||||
|
|
||||||
|
RUN apt update \
|
||||||
|
&& apt install -y curl \
|
||||||
|
&& echo "Pulling watchdog binary from Github." \
|
||||||
|
&& curl -sSL https://github.com/openfaas/faas/releases/download/0.9.6/fwatchdog > /usr/bin/fwatchdog \
|
||||||
|
&& chmod +x /usr/bin/fwatchdog
|
||||||
|
|
||||||
|
WORKDIR /home/app
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
COPY function/shard.yml shard.yml
|
||||||
|
RUN shards install
|
||||||
|
RUN crystal build main.cr -o handler --release
|
||||||
|
|
||||||
|
FROM crystallang/crystal:1.8.0
|
||||||
|
RUN apt install ca-certificates
|
||||||
|
|
||||||
|
# Add non root user
|
||||||
|
RUN adduser app
|
||||||
|
RUN mkdir -p /home/app
|
||||||
|
|
||||||
|
WORKDIR /home/app
|
||||||
|
|
||||||
|
COPY --from=builder /usr/bin/fwatchdog .
|
||||||
|
COPY --from=builder /home/app/function/ .
|
||||||
|
COPY --from=builder /home/app/handler .
|
||||||
|
|
||||||
|
RUN chown -R app /home/app
|
||||||
|
|
||||||
|
USER app
|
||||||
|
|
||||||
|
ENV fprocess="./handler"
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=2s CMD [ -e /tmp/.lock ] || exit 1
|
||||||
|
|
||||||
|
CMD ["./fwatchdog"]
|
7
template/crystal/function/handler.cr
Normal file
7
template/crystal/function/handler.cr
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
require "json"
|
||||||
|
|
||||||
|
class Handler
|
||||||
|
def run(req : String)
|
||||||
|
return JSON::Any.new("Hello, Crystal. You said: #{req}")
|
||||||
|
end
|
||||||
|
end
|
7
template/crystal/function/shard.yml
Normal file
7
template/crystal/function/shard.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
name: crystal_faas_function
|
||||||
|
version: 0.1.0
|
||||||
|
|
||||||
|
# dependencies:
|
||||||
|
# pg:
|
||||||
|
# github: will/crystal-pg
|
||||||
|
# version: "~> 0.5"
|
11
template/crystal/main.cr
Normal file
11
template/crystal/main.cr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Copyright (c) Thomas Peikert 2018. All rights reserved.
|
||||||
|
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
require "json"
|
||||||
|
require "./function/handler"
|
||||||
|
|
||||||
|
req = STDIN.gets_to_end
|
||||||
|
handler = Handler.new
|
||||||
|
res = handler.run req
|
||||||
|
|
||||||
|
puts res
|
@ -1,6 +1,6 @@
|
|||||||
language: crystal
|
language: crystal
|
||||||
fprocess: ./handler
|
fprocess: ./handler
|
||||||
welcome_message: |
|
welcome_message: |
|
||||||
You have created a new function which uses crystal 1.0.0.
|
You have created a new function which uses crystal 1.7.3 🎉
|
||||||
To include third-party dependencies, use a vendoring tool like shards:
|
To include third-party dependencies, use a vendoring tool like shards:
|
||||||
shards documentation: https://github.com/crystal-lang/shards
|
shards documentation: https://github.com/crystal-lang/shards
|
63
template/python3-flask/Dockerfile
Normal file
63
template/python3-flask/Dockerfile
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
ARG PYTHON_VERSION=3.11
|
||||||
|
FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/of-watchdog:0.9.10 as watchdog
|
||||||
|
FROM --platform=${TARGETPLATFORM:-linux/amd64} python:${PYTHON_VERSION}-alpine as build
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
RUN apk --no-cache add openssl-dev ${ADDITIONAL_PACKAGE}
|
||||||
|
|
||||||
|
# Add non root user
|
||||||
|
RUN addgroup -S app && adduser app -S -G app
|
||||||
|
RUN chown app /home/app
|
||||||
|
|
||||||
|
USER app
|
||||||
|
|
||||||
|
ENV PATH=$PATH:/home/app/.local/bin
|
||||||
|
|
||||||
|
WORKDIR /home/app/
|
||||||
|
|
||||||
|
COPY --chown=app:app index.py .
|
||||||
|
COPY --chown=app:app requirements.txt .
|
||||||
|
|
||||||
|
USER root
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Build the function directory and install any user-specified components
|
||||||
|
USER app
|
||||||
|
|
||||||
|
RUN mkdir -p function
|
||||||
|
RUN touch ./function/__init__.py
|
||||||
|
WORKDIR /home/app/function/
|
||||||
|
COPY --chown=app:app function/requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir --user -r requirements.txt
|
||||||
|
|
||||||
|
#install function code
|
||||||
|
USER root
|
||||||
|
|
||||||
|
COPY --chown=app:app function/ .
|
||||||
|
|
||||||
|
|
||||||
|
FROM build as test
|
||||||
|
ARG TEST_COMMAND=tox
|
||||||
|
ARG TEST_ENABLED=true
|
||||||
|
RUN [ "$TEST_ENABLED" = "false" ] && echo "skipping tests" || eval "$TEST_COMMAND"
|
||||||
|
|
||||||
|
FROM build as ship
|
||||||
|
WORKDIR /home/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"]
|
0
template/python3-flask/function/__init__.py
Normal file
0
template/python3-flask/function/__init__.py
Normal file
7
template/python3-flask/function/handler.py
Normal file
7
template/python3-flask/function/handler.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
def handle(req):
|
||||||
|
"""handle a request to the function
|
||||||
|
Args:
|
||||||
|
req (str): request body
|
||||||
|
"""
|
||||||
|
|
||||||
|
return req
|
10
template/python3-flask/function/handler_test.py
Normal file
10
template/python3-flask/function/handler_test.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from .handler import handle
|
||||||
|
|
||||||
|
# Test your handler here
|
||||||
|
|
||||||
|
# To disable testing, you can set the build_arg `TEST_ENABLED=false` on the CLI or in your stack.yml
|
||||||
|
# https://docs.openfaas.com/reference/yaml/#function-build-args-build-args
|
||||||
|
|
||||||
|
def test_handle():
|
||||||
|
# assert handle("input") == "input"
|
||||||
|
pass
|
0
template/python3-flask/function/requirements.txt
Normal file
0
template/python3-flask/function/requirements.txt
Normal file
41
template/python3-flask/function/tox.ini
Normal file
41
template/python3-flask/function/tox.ini
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# If you would like to disable
|
||||||
|
# automated testing during faas-cli build,
|
||||||
|
|
||||||
|
# Replace the content of this file with
|
||||||
|
# [tox]
|
||||||
|
# skipsdist = true
|
||||||
|
|
||||||
|
# You can also edit, remove, or add additional test steps
|
||||||
|
# by editing, removing, or adding new testenv sections
|
||||||
|
|
||||||
|
|
||||||
|
# find out more about tox: https://tox.readthedocs.io/en/latest/
|
||||||
|
[tox]
|
||||||
|
envlist = lint,test
|
||||||
|
skipsdist = true
|
||||||
|
|
||||||
|
[testenv:test]
|
||||||
|
deps =
|
||||||
|
flask
|
||||||
|
pytest
|
||||||
|
-rrequirements.txt
|
||||||
|
commands =
|
||||||
|
# run unit tests with pytest
|
||||||
|
# https://docs.pytest.org/en/stable/
|
||||||
|
# configure by adding a pytest.ini to your handler
|
||||||
|
pytest
|
||||||
|
|
||||||
|
[testenv:lint]
|
||||||
|
deps =
|
||||||
|
flake8
|
||||||
|
commands =
|
||||||
|
flake8 .
|
||||||
|
|
||||||
|
[flake8]
|
||||||
|
count = true
|
||||||
|
max-line-length = 127
|
||||||
|
max-complexity = 10
|
||||||
|
statistics = true
|
||||||
|
# stop the build if there are Python syntax errors or undefined names
|
||||||
|
select = E9,F63,F7,F82
|
||||||
|
show-source = true
|
41
template/python3-flask/index.py
Normal file
41
template/python3-flask/index.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# 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 waitress import serve
|
||||||
|
import os
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# distutils.util.strtobool() can throw an exception
|
||||||
|
def is_true(val):
|
||||||
|
return len(val) > 0 and val.lower() == "true" or val == "1"
|
||||||
|
|
||||||
|
@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):
|
||||||
|
raw_body = os.getenv("RAW_BODY", "false")
|
||||||
|
|
||||||
|
as_text = True
|
||||||
|
|
||||||
|
if is_true(raw_body):
|
||||||
|
as_text = False
|
||||||
|
|
||||||
|
ret = handler.handle(request.get_data(as_text=as_text))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
serve(app, host='0.0.0.0', port=5000)
|
3
template/python3-flask/requirements.txt
Normal file
3
template/python3-flask/requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
flask
|
||||||
|
waitress
|
||||||
|
tox==3.*
|
2
template/python3-flask/template.yml
Normal file
2
template/python3-flask/template.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
language: python3-flask
|
||||||
|
fprocess: python index.py
|
Loading…
Reference in New Issue
Block a user