switch to python
This commit is contained in:
parent
0e688f08e9
commit
1b0177a6f0
35
README.md
35
README.md
@ -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
3
app.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec python -m parliament "$(dirname "$0")"
|
63
func.py
Normal file
63
func.py
Normal 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
|
@ -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
|
||||
|
41
handle.go
41
handle.go
@ -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()
|
||||
}
|
@ -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
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
parliament-functions==0.1.0
|
13
test_func.py
Normal file
13
test_func.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user