2

I have an action in IBM Cloud Functions that only receives one parameter: "frame". I'm using Postman to test the REST API endpoint provided with the action. However, when I provide the "frame" parameter it returns the following:

"response": {
        "result": {
            "error": "'frame'"
        },
        "status": "application error",
        "success": false
    }

I've experienced this problem when I invoke this action in the IBM Cloud Functions' console. I resolve it by erasing a space in the input modal and adding it again, then it works like a charm in the console. However, I can't do the same thing with an HTTP request.

The way I'm currently doing the HTTP request is like this:

POST https://us-south.functions.cloud.ibm.com/api/v1/namespaces/{namespace}/actions/{action_name}?blocking=true&frame={value}

The action should return the result I'm expecting but it doesn't do that right now. Please help me, any answers would be great!

EDIT:

This is the action's code:

import requests, base64, json, cv2
from PIL import Image
from six import BytesIO

def json_to_dict(json_str):
    return json.loads(json.dumps(json_str))

def frame_to_bytes(frame):
    frame_im = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    pil_im = Image.fromarray(frame_im)
    stream = BytesIO()
    pil_im.save(stream, format="JPEG")
    stream.seek(0)
    img_for_post = stream.read()
    img_base64 = base64.b64encode(img_for_post)
    return img_base64

def main(dict):
    cap = cv2.VideoCapture(dict['frame'])
    if not cap.isOpened():
        return { "error": "Unable to open video source" }
    ret, frame = cap.read()
    if ret is False:
        return { "error": "Unable to read video source" }

    # openALPR API part
    OPENALPR_SECRET_KEY = {my_secret_key}
    url = "https://api.openalpr.com/v2/recognize_bytes?recognize_vehicle=1&country=us&secret_key=%s" % (
        OPENALPR_SECRET_KEY)
    r = requests.post(url, data=frame_to_bytes(frame))
    resp = json_to_dict(r.json())
    print(resp)
    if not resp['results']:
        return { "error": "Plate number not recognized" }
    plates = []
    for plate in resp['results']:
        if plate['confidence'] < 75:
            pass
        else:
            print(plate['plate'])
            plates.append(plate['plate'])
    return { "plates": plates  }

This is the activation response (the status returned was 502 Bad Gateway according to Postman):

{
    "activationId": "5a83396b9f53447483396b9f53e47452",
    "annotations": [
        {
            "key": "path",
            "value": "{namespace}/{name}"
        },
        {
            "key": "waitTime",
            "value": 5531
        },
        {
            "key": "kind",
            "value": "python:3.7"
        },
        {
            "key": "timeout",
            "value": false
        },
        {
            "key": "limits",
            "value": {
                "concurrency": 1,
                "logs": 10,
                "memory": 1024,
                "timeout": 60000
            }
        },
        {
            "key": "initTime",
            "value": 3226
        }
    ],
    "duration": 3596,
    "end": 1560669652454,
    "logs": [],
    "name": "{name}",
    "namespace": "{namesapce}",
    "publish": false,
    "response": {
        "result": {
            "error": "'frame'"
        },
        "status": "application error",
        "success": false
    },
    "start": 1560669648858,
    "subject": "{my_email}",
    "version": "0.0.7"
}

EDIT 2: I've also tried to enable it as a web action to see if it changes anything. However, it's no use. When I use this HTTP request:

https://us-south.functions.cloud.ibm.com/api/v1/web/{namespace}/default/{action_name}?frame={value}

I get:

{
    "code": "e1c36666f4db1884c48f028ef58243fc",
    "error": "Response is not valid 'message/http'."
}

which is understandable since what my functions returns is json. However, when I use this HTTP request:

https://us-south.functions.cloud.ibm.com/api/v1/web/{namespace}/default/{action_name}.json?frame={value}

I get:

{
    "code": "010fc0efaa29f96b47f92735ff763f50",
    "error": "Response is not valid 'application/json'."
}

I really don't know what to do here

1 Answers1

0

After googling a bit I found something that works for me right now although it might not work for everyone. Apache has a python "client" example for using an action's REST API which uses the requests library.

Thing is that in order to use it you need to provide your API KEY, which I don't know how to get by any other means than getting it directly from the IBM Cloud CLI. Since I'm trying to access the function from a web server, I would need to save the key in an environment variable or save it in a text file and access it from there or install the CLI on the server, login with my credentials and call ibmcloud wsk property get --auth.

Also, this method didn't work with the web action endpoint when I tried it.