switch to python

This commit is contained in:
Adrien le Maire 2023-12-08 16:24:52 +01:00
parent 0e688f08e9
commit 1b0177a6f0
10 changed files with 106 additions and 86 deletions

1
Procfile Normal file
View File

@ -0,0 +1 @@
web: python -m parliament .

View File

@ -1,20 +1,29 @@
# Go HTTP Function
# Python HTTP Function
Welcome to your new Go Function! The boilerplate function code can be found in
[`handle.go`](handle.go). This Function responds to HTTP requests.
Welcome to your new Python function project! The boilerplate function
code can be found in [`func.py`](./func.py). This function will respond
to incoming HTTP GET and POST requests.
## Development
## Endpoints
Develop new features by adding a test to [`handle_test.go`](handle_test.go) for
each feature, and confirm it works with `go test`.
Running this function will expose three endpoints.
Update the running analog of the function using the `func` CLI or client
library, and it can be invoked from your browser or from the command line:
* `/` The endpoint for your function.
* `/health/readiness` The endpoint for a readiness health check
* `/health/liveness` The endpoint for a liveness health check
The health checks can be accessed in your browser at
[http://localhost:8080/health/readiness]() and
[http://localhost:8080/health/liveness]().
You can use `func invoke` to send an HTTP request to the function endpoint.
## Testing
This function project includes a [unit test](./test_func.py). Update this
as you add business logic to your function in order to test its behavior.
```console
curl http://myfunction.example.com/
python test_func.py
```
For more, see [the complete documentation]('https://github.com/knative/func/tree/main/docs')

3
app.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
exec python -m parliament "$(dirname "$0")"

63
func.py Normal file
View File

@ -0,0 +1,63 @@
from parliament import Context
from flask import Request
import json
# parse request body, json data or URL query parameters
def payload_print(req: Request) -> str:
if req.method == "POST":
if req.is_json:
return json.dumps(req.json) + "\n"
else:
# MultiDict needs some iteration
ret = "{"
for key in req.form.keys():
ret += '"' + key + '": "'+ req.form[key] + '", '
return ret[:-2] + "}\n" if len(ret) > 2 else "{}"
elif req.method == "GET":
# MultiDict needs some iteration
ret = "{"
for key in req.args.keys():
ret += '"' + key + '": "' + req.args[key] + '", '
return ret[:-2] + "}\n" if len(ret) > 2 else "{}"
# pretty print the request to stdout instantaneously
def pretty_print(req: Request) -> str:
ret = str(req.method) + ' ' + str(req.url) + ' ' + str(req.host) + '\n'
for (header, values) in req.headers:
ret += " " + str(header) + ": " + values + '\n'
if req.method == "POST":
ret += "Request body:\n"
ret += " " + payload_print(req) + '\n'
elif req.method == "GET":
ret += "URL Query String:\n"
ret += " " + payload_print(req) + '\n'
return ret
def main(context: Context):
"""
Function template
The context parameter contains the Flask request object and any
CloudEvent received with the request.
"""
# Add your business logic here
print("Received request")
if 'request' in context.keys():
ret = pretty_print(context.request)
print(ret, flush=True)
return payload_print(context.request), 200
else:
print("Empty request", flush=True)
return "{}", 200

View File

@ -1,7 +1,7 @@
specVersion: 0.35.0
name: hello
runtime: go
created: 2023-12-07T19:54:11.056629+01:00
name: hello2
runtime: python
created: 2023-12-08T16:20:58.104476+01:00
build:
git:
url: https://git.le-maire.eu/alemaire/knative-function.git # required, git repository with the function source code

3
go.mod
View File

@ -1,3 +0,0 @@
module function
go 1.14

View File

@ -1,41 +0,0 @@
package function
import (
"context"
"fmt"
"net/http"
"strings"
)
// Handle an HTTP Request.
func Handle(ctx context.Context, res http.ResponseWriter, req *http.Request) {
/*
* YOUR CODE HERE
*
* Try running `go test`. Add more test as you code in `handle_test.go`.
*/
fmt.Println("Received request")
fmt.Println(prettyPrint(req)) // echo to local output
fmt.Fprintf(res, prettyPrint(req)) // echo to caller
}
func prettyPrint(req *http.Request) string {
b := &strings.Builder{}
fmt.Fprintf(b, "%v %v %v %v\n", req.Method, req.URL, req.Proto, req.Host)
for k, vv := range req.Header {
for _, v := range vv {
fmt.Fprintf(b, " %v: %v\n", k, v)
}
}
if req.Method == "POST" {
req.ParseForm()
fmt.Fprintln(b, "Body:")
for k, v := range req.Form {
fmt.Fprintf(b, " %v: %v\n", k, v)
}
}
return b.String()
}

View File

@ -1,26 +0,0 @@
package function
import (
"context"
"net/http"
"net/http/httptest"
"testing"
)
// TestHandle ensures that Handle executes without error and returns the
// HTTP 200 status code indicating no errors.
func TestHandle(t *testing.T) {
var (
w = httptest.NewRecorder()
req = httptest.NewRequest("GET", "http://example.com/test", nil)
res *http.Response
)
Handle(context.Background(), w, req)
res = w.Result()
defer res.Body.Close()
if res.StatusCode != 200 {
t.Fatalf("unexpected response code: %v", res.StatusCode)
}
}

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
parliament-functions==0.1.0

13
test_func.py Normal file
View File

@ -0,0 +1,13 @@
import unittest
func = __import__("func")
class TestFunc(unittest.TestCase):
def test_func_empty_request(self):
resp, code = func.main({})
self.assertEqual(resp, "{}")
self.assertEqual(code, 200)
if __name__ == "__main__":
unittest.main()